Guarantees

Stable externally-observable behavior of the measurement system. Implementation may change; these guarantees hold across versions.


Input Contract

The measurement system requires a stream of structured events. The implementation consumes Claude Code JSONL transcripts and DeepSeek Harness session event logs; the input schema below describes the logical contract both fulfill and any further adapter would.

Usage snapshot: Each API interaction produces a snapshot containing:

Context-reset signal: A structural indicator that the context window has been cleared or compacted. It comes from transcript topology alone — a drop in reported token totals is not one, however steep. The measurement system uses it to trigger segment boundaries.

Tool-event stream: Each tool call's input and result text. To compute per-path token contributions to B, the system reads the files the call names and matches the call's text against their lines, whichever tool or command printed or wrote them. A line that matches counts toward its file, at the line where the file holds it; every other character, and the text of a file that is missing, unreadable or binary, counts toward the residual.


Measurement Invariants

Given correct input, the measurement layer guarantees:

Folding: When multiple snapshots share the same primary key, only the revision with the highest total token count is retained. Earlier or partial revisions are silently replaced. A fold revision never triggers a segment boundary.

Segment isolation: On context-reset, the accumulated cost state resets: B rebuilds from zero, g returns to floor, the deferred ledger clears, the model a segment's reads resolve against is cleared for the next call to fix, and the rate lamp starts a fresh billing cycle. What survives is the turn count and an unconsumed turn boundary, so a user turn already announced still opens its turn on the far side of the reset. Cross-segment history is preserved for visualization but does not contaminate current measurements.

Token-at-Ingestion: Per-path token estimates are computed once at write time using a model-specific conversion ratio. Values are never retroactively recomputed — changes in calibration or file content only affect future observations.

Settlement: When B grows faster than L (cache-creation credited before cache-read materializes), the surplus is banked in a deferred ledger as credit L has yet to confirm, and retires as L catches up. Any balance un-retired at segment end is treated as estimation error and corrected out of the path totals.

Sidechain exclusion: A row marked as sidechain is a self-contained sub-agent context and is dropped before interpretation, so it yields no evidence of any kind: it contributes to L, g, segmentation triggers, turn counting and path attribution alike not at all, and its identifiers never reach topology.


Output Semantics

The system publishes a status snapshot after each measurement cycle. Consumers can rely on:

Position constraint: The public field B never exceeds totalStock. This cap is a transient display guard during cache-creation lag; it self-releases once the provider's cache catches up. Internal decision math uses B_default (the filtered subset) as its position basis.

Baseline validity gate: The system requires a positive position basis (B_default) AND cRatio > 0 to produce meaningful cost metrics. When either condition fails:

The system overhead floor is anchored by the first usage snapshot with a positive context stock, as that stock less the content already tracked as resident per file, skill and tool, never below zero, and is part of B_default. B_default is therefore positive from that snapshot on without any file operation, except when the whole stock was already tracked as resident and the inclusion filter selects none of it.

Left-arm silence: Which arm the session is on is decided by normalized position, never by the position ratio against xSweet. Before the sweet spot the lamp shows white until the position reaches the mirror image of the amber boundary and green from there on; the warning and critical zones are right-arm states only, so a session that has not reached the sweet spot is never coloured as "overstaying."

Restart reminder: The reminder is raised by the rent ledger and by nothing else. Each measured call adds its rent increment to a wallet phase scaled by the reminder interval, and a call whose increment carries that phase across a lap boundary raises a reminder stamped with the lap count reached and wraps the phase, so a call that crosses several boundaries is announced by that stamp rather than by a reminder per lap. Rent already accumulated is settled: a revaluation — by a baseline change, a change of selected files, or a price change — withdraws no reminder already raised and rewinds no phase already advanced.

Rate-lamp integration: One rent increment per measured call, formed by trapezoidal accumulation across the call's interval, feeds two counters: a bill cycle, which is display only and triggers nothing, and the wallet phase, whose lap boundary is what raises the reminder. Reminders therefore follow accumulated cost rather than an instantaneous bp spike. The reminder interval adapts to mf — higher stakes shorten it; lower stakes lengthen it.


Persistence Boundary

Segment profiles: On each segment boundary and at shutdown, a summary profile is archived to persistent storage. This includes exit metrics (B, L peak, g, br, mf, turns, duration) — enough to reconstruct cross-segment trends.

Per-call time series: The full call-by-call history lives only in process memory. On resume, the system reconstructs it by re-reading the transcript from byte zero — the same interpretation the live path applies, with each call's file attribution taken from the record stored when the call was first observed, so the rebuilt series is the one live observation produced. A call with no stored record is matched against the files as they are at that moment. If the transcript file is lost, per-call history is unrecoverable; only the archived segment profiles remain.

Attribution records: For each tool call observed live, the files and line numbers its text was attributed to are stored with the session, together with each line's character count and a hash of it, and the name of the tool or command that made the call (for a shell command, also its main argument), but no file content; they are deleted with the session.

Rate-lamp ledger: The billing ledger is persisted independently via periodic checkpoints. An unclean exit may lose recent state. On restart, the system loads the last valid checkpoint; if none is usable, it starts a fresh ledger.


Hook Behavior

The session-start hook fires on startup, resume, clear, and compact. Its observable effects:

Handoff discovery: On startup and clear, the hook queries persistent storage for undelivered handoffs belonging to the current project. When found, it injects a reminder into the session context containing the load token, age, and task preview. On resume, handoff discovery is skipped — the session already has context.

Server rotation: When the hook detects a session-id mismatch (new session connecting to a running server), it issues a rotation request. The server archives the current segment and switches to the new transcript. If rotation fails, a fallback context is injected instructing the agent to call rotate_session manually.

Bounded best-effort: The hook always exits zero and its execution is capped by the host's command timeout. Any failure (database unavailable, server unreachable, parse error) is silently absorbed — the session starts with or without measurement context.


MCP Tools

Stable commands exposed to the agent. The Claude Code plugin and the DSH plugin register the same tools, except where the table says otherwise.

Tool Purpose
watcher_status Report whether the watcher is running and one session's current reading: lamp, wallet-clock phase, br, u, gEma, L, B, model and alert, the quantities the statusline shows; while the session is still measuring, reliable is false and lamp, phase, br, u, gEma and alert are null, with model, L and B still reported. The Claude Code reply reads its own session and also carries the dashboard URL. The DSH reply carries no URL, since DSH serves no dashboard, and an optional sessionId names the session to read: any session the host has run or persisted, a settled one rebuilt first
get_bucket_summary The handoff decision's view of the context buckets: each file or skill row with its token size, read and edit counts, default selection with its reason, the user's override and, for a default-selected file, its active symbols, beside the session id, the segment and br. No other metric is returned
get_turn_skeleton Write the current context epoch's turn skeleton and a notes file whose ## NOTE[T] headings are the slots a note fills; returns both paths, the snapshot id to submit against and the protocol for filling them
submit_turn_notes Commit the notes file the latest skeleton wrote. All-or-nothing: every NOTE slot must be covered, by a section of the file or by a note the store already holds, and the snapshot must still be current
prepare_handoff Persist the kept paths and a summary as a handoff package; returns a load token
load_handoff Claude Code only: retrieve a handoff package by token, free-text search or auto-match for the project. Delivering a package binds it to the loading session and records the load, so the tool writes. A delivered package carries the newest lineage headlines within a budget, the older sessions collapsed into runs marked omitted, and the newest page of turns
rotate_session Claude Code only: switch the watcher to a new session and transcript
turn_page Read a page of the history turns carried by the loaded handoff, newest first
turn_search Find a literal that occurs verbatim in the transcripts behind the loaded handoff
turn_locate Find which turn ranges mention a remembered term, when the source wording is unknown
lineage_headlines Read the headlines of chosen sessions of the loaded handoff's lineage, such as an omitted run of the load reply's lineage, by their positions k (S2-S5 is 2-5)

The three history tools and lineage_headlines resolve their own lineage from the handoff delivered into the calling session, so none of them accepts a lineage identifier: a session that has loaded nothing is told so rather than offered a guess. Paging is deterministic and needs no query; the two query tools are distinguished by what the caller actually remembers. Every search or locate result names what to do with it — follow a hit, narrow a truncated match set, or switch tools on a miss — while a page that was built simply arrives.

On DSH the model has no load_handoff tool; the human command /sw-load, described on the DSH page, delivers the handoff, records the load and renames the loading session after the package's next task. The human command /sw-continue takes no arguments and clears the session in place: it shadows the session's history behind a checkpoint that opens a new epoch, then loads the session's newest handoff itself, delivering and reading it as /sw-load does, and hands the model the result. The follow-up has the model resume the task in the same turn after a one-sentence note on what it resumes, where the follow-up of /sw-load has it present the loaded state and wait for confirmation, and has the model ask any question, approval or permission the task left open and wait for the user. It leaves the session untouched and says why when the session has prepared no handoff, when its newest handoff was prepared before the latest context reset, or while the agent is busy. When the clear succeeds and the load fails, the clear stands and the answer carries the reason and the token to load by hand with /sw-load <token>. The session's earlier epochs stay readable as their own lineage entries, each with the turns up to the handoff it produced.


Degradation

Transcript missing: The system reports white lamp with reason no_transcript. Cost-model outputs fall back to their defined invalid-state defaults. Measurement resumes automatically when the transcript becomes available.

Transcript corrupt or unparseable: Partially readable content is processed up to the last valid entry. Corrupt trailing bytes are skipped. Metrics reflect only the successfully parsed portion.

Database unavailable: Persistence failures during operation (handoff discovery, segment archival, turn-record writes) degrade independently — each fails open without stopping measurement.

Interpretation fails outright: An error the system cannot classify as an unreadable or malformed source is treated as a defect rather than absorbed: measurement stops, the owner reports the error, releases what it holds without archiving the open segment, and exits nonzero. The transcript is left untouched, so a fresh owner rebuilds from it.

Server unreachable during rotation: The hook injects fallback context instructing the agent to call rotate_session manually.