The v1.2 release. Claude Code remembers across compactions and sessions.
SessionStart now emits a token-budgeted reference bundle instead of a
2-5K text dump; the agent pulls depth on demand via existing MCP tools.
Behavior contracts let you teach Claude durable preferences once and have
them ride into every session. An OpenTelemetry-shaped span substrate
underneath both features makes the message graph queryable through the
new lcc_expand span_id mode.
Compaction-aware reference bundle (the headline). inject_context.py
no longer dumps the full dream-patterns text plus top summaries. Instead,
SessionStart receives a slot-packed reference bundle ordered with the
recovery-protocol line first so the agent learns the recovery contract
before any content. Default cap 1000 tokens, configurable via
bundleTokenBudget. Each item carries a literal Expand: call MCP tool
instruction the agent can invoke verbatim. PreCompact and PostCompact
hooks stay no-push (hooks/post_compact.sh:54-56 constraint preserved
verbatim). Recovery routes entirely through the SessionStart bundle's
recovery line plus agent-initiated MCP calls.
Behavior contracts. New contracts table with typed kind
(prefer / forbid / verify-before), bylined, append-only with a
supersedes_id chain. The dream cycle proposes contracts as Pending;
the new TUI Contracts tab (key 5) lets you approve (a), reject /
retract (r), or supersede (s) interactively. Filter cycle (t)
flips between Pending, Active, and Retracted views. Every Active
contract rides in the SessionStart bundle's contracts slot.
OpenTelemetry-shaped span substrate. messages gains four new
NULL-able columns: parent_message_id, span_kind, tool_call_id,
attributes (JSON). Hooks populate them at write time. New
scripts/db/spans.py exposes get_span, get_span_chain,
get_children_spans, cap_attributes_json. lcc_expand accepts
span_id and walks the parent chain; structured-error JSON returns
(span_not_found / expand_too_large / vault_corrupt /
permission_denied) with sanitized static messages so error output
can never leak filesystem paths or library internals into agent
context.
- Bundle token budget (
bundleTokenBudget, default 1000) and thebundleEnabledrollback flag (defaulttrue). SetbundleEnabled: falsein~/.lossless-code/config.jsonto disable SessionStart injection entirely while keeping all other lossless-code features active. lcc_contractsMCP tool andlcc contractsCLI verb. Actions:list,show,approve,reject,retract,supersede. Same result shape on both surfaces; structured-error JSON for new MCP errors with sanitized static messages.lcc_expand span_idmode plus structured errors. Existingsummary_idandfilemodes preserve their v1.1.x human-readable output for backwards compatibility.- TUI Contracts tab with full state coverage: Pending / Active /
Retracted filter cycling via
t, ContractDetailScreen modal for the full body before approval, SupersedeBodyScreen TextArea modal for in-place revision, RetractionReasonPrompt for required-reason retracts, conflict-signal column when an opposing-kind Active rule overlaps the candidate. collect_status_dictshared helper inscripts/lcc_core.py. Bothlcc statusand thelcc_statusMCP tool now route through this single source of truth, closing a historical CLI-vs-MCP drift pattern. New v1.2 fields surfaced in status: contract counts by status, decision count, bundle enabled state and budget,lastDreamMode(whether the dream cycle ran via LLM, regex fallback, or failed).
- Vault permissions.
~/.lossless-code/now ships withmode=0o700on the directory,0o600onvault.dbandconfig.json. Closes the world-readable gap that v1.2's newcontracts.bodyandmessages.attributescolumns would otherwise inherit on shared machines. - Contract body sanitization at injection time. Bundle assembler
strips
\nand\rfrom contract bodies and rejects bodies containing the literal[lcc.contract]marker. Closes the newline injection vector flagged in v1.2 doc review: without this, an attacker who got an approved contract body with embedded\n[lcc.contract] FORBID poisonwould see a synthetic second contract line in the SessionStart bundle. - Supersede atomicity.
supersede_contractwraps INSERT new and UPDATE old inBEGIN IMMEDIATE/COMMITso concurrent CLI + MCP writes cannot land two rival Active rows pointing at the same target. attributesJSON shape validation.store_messagerejects non-dict attributes input (logged to stderr, stored as empty object);cap_attributes_jsontoken-caps oversize payloads with a tombstone preserving the size signal.
- Legacy v1.1 full-text injection from
inject_context.py. The reference bundle is now the only injection path. SetbundleEnabled: falseto disable SessionStart injection entirely if you want the v1.1 behavior of "no lossless-code context layer." No compatMode dual-path is shipped; the previous proposal was rejected during plan review as a complexity tax for a measurement that can be done once pre-merge.
install.sh now detects when both manual and plugin installs are
present and emits a stderr warning with one-liner remediation paths.
The lcc doctor self-healing tool remains deferred to v1.3.
- Existing installs: re-run
install.shto pick up the two new scripts (scripts/contracts.py,scripts/lcc_core.py). Plugin users get the upgrade through the marketplace refresh. - First dream cycle post-v1.2: the dream cycle now runs Phase 1.5 (contract + decision extraction) after pattern extraction. Pending contracts populate the TUI queue; nothing rides in the bundle until you approve.
- Schema migrations: idempotent
ALTER TABLEadds five columns (4 onmessagesfor spans, 1 ondream_logformode) plus thecontractstable. NULL-permissive for backfill compatibility; pre-v1.2 rows have no causal data and that is accepted.
Patch release that ships every main-branch delta accumulated since the
v1.1.0 marketplace artifact, headlined by the claude --print CWD fix
that closes the claude --resume pollution bug. Marketplace users
should upgrade to pick up the fix; manual installs already covered by
re-running install.sh.
claude --printsubprocess CWD pollution (PR #11). The summariser'sclaude --printcalls now pincwd=to~/.lossless-code/.cli-cwd, so Claude Code files internal summarisation sessions in their own bucket instead of polluting the user'sclaude --resumelist with hundreds of "Summarise the following conversation turns concisely…" entries. Includesscripts/check_summariser_pollution.pyregression detector.- Installer + README sync for fingerprint feature (PR #10).
install.shnow copies the new PreToolUse / PostToolUse hooks and thescripts/file_context.py,scripts/hook_store_tool_call.pyfiles added by the fingerprint feature; README documents the newfileContextEnabledflag and the hook surface.
fileContextEnabledconfig flag (defaultfalse) gates all new behavior. Flip totruein~/.lossless-code/config.jsonto opt in.- Schema additions:
messages.file_path,summaries.kind, plusidx_messages_file_path(partial) andidx_summary_sources_sourcecomposite. Migrations are idempotent. - PostToolUse hook (
hook_store_tool_call.py) records which file aRead | Edit | Write | MultiEdit | NotebookEdittool call touched. - Polarity classification (
summarise.classify_chunk_polarity) tags summaries ascreated | edited | discussed | mixedbased on the tool calls in the chunk; propagates through cascade. db.get_summaries_for_filewalkssummary_sourcesupward from a message'sfile_pathvia recursive CTE (hop ceiling 16) and excludes consolidated nodes.inject_context.format_file_fingerprintrenders a compact, 200-token fingerprint with a truncation ladder that always preserves the file path and thelcc_expandhint.- PreToolUse hook (
pre_tool_use.sh+scripts/file_context.py) injects the fingerprint asadditionalContextbefore file-touching tools run. Reads are served from a JSON cache undercache/with 60s TTL, file-locked reads/writes, atomic replace, and single-flight stampede guard. Cold path opens vault.db read-only so it never blocks the writer. lcc_expand --file <path>(CLI) and{"file": "..."}(MCP) drill from a file path to the recent summaries that reference it.lcc statussurfaces tagged message count, distinct tagged files, and cached fingerprint count when the flag is on.
scripts/db.pysplit intoscripts/db/package (PR #8). Single 745-line module replaced with focused submodules:config,schema,messages,summaries,sessions,embeddings,search,dream_log. Public import surface is preserved viascripts/db/__init__.py; existing call sites unchanged.- BM25 prompt-aware context eviction (PR #7). Context injection now scores candidate summaries against the live prompt with BM25 instead of a flat recency cut, so high-signal older summaries survive eviction when the prompt actually references them.
- Session filtering for lossless-claw v0.7.0 parity: stateless session gate, stop-hook filtering, plus DB-layer tests covering pattern matching and filter behaviour.
- Circuit breaker + dynamic chunk sizing for summarisation: protects the summariser from runaway provider failures and adapts chunk size to the active provider's context window.
- Vault bloat protection: summary size caps and dream pagination prevent unbounded growth on long-running vaults.
claude-cliprovider for Claude Max / Pro subscription users (no API key path).ANTHROPIC_API_KEYis stripped from the subprocess env so the CLI falls back to OAuth.- Custom Anthropic-compatible providers (MiniMax and others) via
openaiBaseUrl, plus provider auto-detection and structured error handling. dream --statusflag for inspecting dream-cycle state.
- Hybrid semantic search combining FTS5 BM25 with vector similarity via
reciprocal rank fusion. Cached
fastembed.TextEmbeddinginstance.