# Architecture

Context Guard separates DSH-owned execution from Guard-owned certification.

## Responsibility boundary

| Module | Owns |
| --- | --- |
| DSH Goal | Persisted objective, automatic goal rounds, pause/resume/block/complete |
| DSH Todo | Lightweight current plan display |
| DSH Compaction | Model-visible history reduction without corrupting tool-call structure |
| Context Guard | Per-item task contract, revisions, evidence binding, and completion certificate |

Context Guard does not own Goal, Todo, Compaction, or continuation. It intervenes when completion is claimed without a valid certificate.

## Call-time Host working-directory evidence

For an ordinary named `npm test` or `pnpm test` Host call that omits `workdir`,
Guard observes the proposed default directory before execution. The observation
binds the original Session header, committed cwd epoch, scoped policy and
`WorkingDirectoryService`, active shell service, and audited DSH `0.2.1-rc.2`
implementation bytes and dependency routes. Its provider-visible context is
deferred until the host has persisted the complete tool-result batch. It is
not a directory returned by the executed process.

Bash and PowerShell obtain their default from the host's asynchronous
`workingDirectory.ensure()`. That service can recover a missing directory after
`tool/call`. Guard therefore withholds the receipt if the current service readback
disagrees or the directory history changes while the call is in flight. The
ordinary call still proceeds; its cwd-dependent result stays unconfirmed and
retains the call-epoch target. An explicit absolute workdir or file target is
bound independently; a relative shell workdir resolves against the call epoch only under the epoch reader. Historical logs with no cwd-change events retain the exact 0.9.0 projection under the same host binding and its frozen evidence/digests, including relative workdir spelling. The reader version is chosen from effective epochs committed through the result, so a future change cannot rewrite a completed legacy fact.

A receipt binds call ID, sequence, turn, arguments digest, root source, Session
and host-lock digests, physical directory and policy root. Replay accepts v1
only in unchanged header history. V2 additionally binds the governing epoch
and the original cwd supplied by the actual Session header, and refuses
in-flight directory changes and transplanted histories. Neither version
creates permission to execute or proves resource cleanup. Missing or ambiguous
provider identity, a lexical filesystem alias, background execution or an absent
receipt leaves the omitted-workdir completion shortcut unavailable. Historical
logs cannot acquire a missing receipt from today's configuration.

## Durable state model

The resolved session mode binding, effective policy configuration and DSH Session append-only log are the ordinary inputs to the rebuildable Guard projection. Context Guard **appends no custom session event types**: the persisted event vocabulary is harness-owned and the current persistence layer refuses unknown event types. The explicit release and restart paths additionally use the provider-invisible private ledger described below. The `activation` configuration selects only a fresh unseeded root binding; the resolved immutable binding supplies initial enablement, while ordinary session state is derived from the natively persisted events DSH already writes:

- immutable session mode binding — initial enablement (`always` is the new-root default; adopted old modes persist; `opt-in` starts disabled and `always` starts enabled before replay);
- `command/run` — later enablement (`/context-guard on|off|clear`) and epoch transitions;
- `user/message` — captured contract clauses;
- `tool/call` + `tool/result` — bounded evidence and completion-certificate attempts;
- `tool/ptc-dispatch-start` + `tool/ptc-dispatch` — evidence for sub-calls dispatched from a `run_code` program. These are the current names; the retired `tool/code-dispatch*` vocabulary is ignored and mints nothing;
- `compaction/summary` — the compaction cut that re-arms the recovery reminder;
- `goal/change` — the recorded Goal reference, revision, and phase used by the completion gate.

Everything else in the DSH log is deliberately ignored. In particular a V3 `system/message` is a plugin-sourced surface node rather than root authority, a compaction checkpoint `user/message` stays plugin context, and `request/header`, `request/context`, `assistant/attempt`, `session/end-seed` and raw `assistant` streams carry no contract state.

The in-memory `GuardProjection` is a rebuildable cache: `deriveProjection` applies the resolved session activation mode, replays the native log deterministically, recomputes every contract, evidence, and certificate, and flags `corrupt` when a recorded certificate no longer re-derives from the evidence in the log. The projection and its evidence are session-scoped: a new DSH session starts a new projection and cannot import, look up, or certify evidence IDs from another session. A completed workflow that needs a certificate must therefore produce its evidence and call `context_guard_checkpoint` in the same session. Under a bound `always` mode, replay begins enabled. Changing a profile default does not change old bindings; a contradictory explicit setting refuses rather than replaying that session under another mode. A recorded `/context-guard off` disables capture from that point until a later `on`. A recorded `/context-guard clear` supersedes every pending requirement and acceptance under a `CLEAR:<revision>` sentinel (prohibitions are retained) and bumps the contract revision, so a fresh empty-binding checkpoint can certify while the guard stays enabled. Captured contracts always carry a concrete subject/surface, so no unrelated evidence can close a requirement.

## Session lifecycle: silent start, first-message activation

The runtime separates what it injects from what it certifies. An internal lifecycle phase — `armed` (protection enabled, waiting for the first real root input), `active` (real input entered a step), `disabled` (explicitly off) — expresses the startup strategy only; certification still depends solely on durable events, the current contract, and the evidence chain.

Session start (`agent/session-start`) registers tools and the runtime, reads history, and arms recovery for resume/compact. It appends nothing, so a fresh session stays blank (`seq === 0`) and a DSH preset can still be selected while the session is new. The Web surface treats a session as blank until a `turn/start` (server preset lock) and falls back to `seq === 0` for cold list entries; Guard writes no message at T0, so both stay satisfiable. Guard reads history only through the DSH Session V3 `snapshotEvents()` API and refuses a session that does not expose it, so no V2 log can be projected as if it had V3 semantics.

At `agent/pre-step` the loop has CLAIMED this step's input but has not persisted it yet. A pure preview reads only the validated claim: under `always`, the first claimed batch that carries a real root user message (non-empty text, or any image/attachment part) injects the `Context Guard protocol boundary: v4.0.0` notice and a compact first-step guidance message ahead of the claimed messages, inside the same step batch. The formal projection never derives from the preview — the boundary and the user message become durable events when the loop appends the batch, and the contract is re-derived from them exactly as from any other log. `opt-in` never auto-injects; delegated/subagent sessions receive no boundary, guidance, or activation (their scope arrives through the parent's delegation prompt). Rejection, cancellation, or a filtered batch injects nothing and retries on the next legal input.

Recovery packets keep the existing content-dedup and ride the next entered step. The first 0.5 write into a pre-0.5 session carries the v4 boundary with it — that message is the explicit version cut: obligations and certificates recorded before it keep the frozen 0.4 rules (including exact-shape rebind replay), while later messages use the 0.5 confirmation grammar.

## Unified diagnosis and preparation

For default v6 ordinary work, the prepare and checkpoint tools display the confirmed shared-core predicates at the current Session watermark. Historical item statuses and certificate bytes remain available for audit, but a pending legacy item does not become a new execution qualification after its current core predicate is satisfied. A separate information requirement remains open until the final answer is durably delivered. The ordinary checkpoint reply is an observation, not a signed certificate; missing or unprojectable core input stays unknown. Explicit proof, adopted Goal and applicable release work retain the versioned certificate path. Pagination binds the shared-core waterline so an older discovery page cannot silently skip changed obligations.

`deriveItemDiagnosis` is the pure historical and explicit-certificate item judge shared by recovery, rebind queries, and those checkpoint, prepare, and status views that use the versioned certificate contract. Default v6 ordinary prepare and checkpoint instead read `currentV6Feedback` from the confirmed shared-core projection; they preserve the original item and source for display without turning old item status into a current qualification. On the certificate path, item diagnosis reports a task kind (`inquiry`/`action`/`constraint`/…), certification support (`unsupported`/`needs_target`/`needs_evidence`/`unavailable`/`supported`), repairability (agent-repairable, needs user input, unsupported, historical gap, none), the exact missing target fields and evidence facets, and one concrete next action with a resume condition and a stable attempt fingerprint. Inquiries stay captured obligations whose honest next step is to deliver the answer; they are never prescribed a rebind. An effect recorded without its resolution prestate is a historical gap: read back observed state, never re-execute to mint evidence.

0.6.2 adds the shared capability projection beside that verdict (`src/domain/capability-semantics.ts`). Every lane declares one gap kind — unknown interpretation, missing target, missing adapter, legacy migration, missing historical pre-evidence, unattributable operation, pending condition, pending delivery, unavailable host, or standing constraint — and exactly one reachable remedy. Every consumer reads that projection instead of inferring a root cause from one enum, which is what stops a capability this build lacks from being reported as a user-authorization gap. Shell facts additionally carry a layered reading (`processFacts`): the host tool's own return, the console's declared exit status or `unknown`, how far the effect was attributed to this obligation's operation, and the resulting business outcome. Those fields are derived at replay, are excluded from every digest and certificate domain, and never rewrite a historical `outcome` or `parseStatus`.

`context_guard_prepare` is read-only. Before a stateful action it renders the supported command shape from the same audited parser the executor uses, the required resolution/effect/state order, reusable evidence references, the host capability verdict, and the exact missing target fields. It performs no action and never turns a guessed default into user authority.

0.6.3 adds one shared compatibility judgement (`src/domain/compatibility.ts`) that both preparation and the mutation gate call for the same item, action, revision and target. It separates four different facts — semantic compatibility (does the action belong to the item's reading?), target compatibility (is the resolved target the one the obligation selected?), execution readiness (pending, authorized, free of an outstanding condition or constraint), and adapter capability — and returns `compatible`, `incompatible` (the assumption is not what the obligation records, with the item's own action named) or `blocked` (the assumption matches but this snapshot cannot execute yet). A caller-supplied action manual is returned as `recipe_only`, and a caller-supplied target the obligation did not select is reported as a proposal, never as authority; the side-effect entry still re-reads every fact, evidence, host lock and identity before acting. The same release adds a pre-terminal eligibility pass: before any terminal filtering, records that earlier versions closed as answered are re-read, and one whose own text still orders work or whose git target has no auditable source is marked `needs_review`. That mark preserves the historical status byte for byte, re-executes nothing, and blocks a new certificate and Goal completion instead of warning about them.

Requested-target provenance (`targetSource`) is recorded beside the target itself: an explicit name or path, a phrase that selects the current repository, a trusted host selection, a unique selection inherited from another obligation of the same work unit, or the environment default. Only the first four are user selections; the environment default is context that can resolve an allowed object but can never authorize one.

A log-derived retry ledger keys each rejected rebind attempt by its stable inputs and outcome. An identical second attempt returns `unchanged` with the resume condition instead of a fresh rejection; new related evidence, a new root instruction, or a changed target produces a new key and re-opens evaluation.

## Synchronization

The runtime rebuilds the projection from the log before each step. Before evidence is produced, the runtime awaits `ctx.sessions.flush(session)`; if no durability listener participated, evidence is marked `durability-unknown`, which fails closed.

The host lock uses `dsh-core/v1`: one exact 33-package DSH core, independent of optional market versions. The resolver walks all reachable runtime/profile dependencies, including those introduced by plugins, and checks installed manifests against lock identities. Missing, duplicated, mixed or changed core rows fail closed. Every replay rechecks the configured graph sources against the injected core identity before deriving certificate authority.

Core manifest version 2 and its policy/cohort values change the digest without changing the shared digest-v3 encoder. Legacy injected configuration requires explicit inspection and migration; historical records are never relabelled. Action capabilities are evaluated only after this core contract succeeds. Market restart additionally requires a trusted loaded-instance verifier. Current DSH supplies none, so restart is unavailable while unrelated guarded work remains supported. A requested restart stays pending. The version-2 service adapter distinguishes ordinary provider/instance drift from a persisted, target-bound restart handoff.

Evidence is produced only from persisted `tool/call` + `tool/result` pairs. Guard never inserts context between a Code Mode sub-call and its durable result.

## Domain pipeline

1. `classifyUserInteraction` drops session-layer utterances before capture: bare progression/acknowledgement phrases (`继续`, `continue`), meta questions (`这个收尾具体要做什么`, `是不是bug`), and meta comments/objections. The classifier fails closed — an artifact path, an explicit method, or a non-negated operation verb always keeps the message (or the individual clause inside a mixed message) a captured instruction.
2. `classifyClause` / `captureClause` classify the remaining direct human message into requirement, acceptance, or prohibition.
3. `segmentAuthorityBlocks` keeps quoted/code/reference material outside the contract, supports explicit section adoption, and captures uncertain material fail-closed.
4. `context_guard_evidence` produces read-only resolution/state facts and validates already persisted effects; `context_guard_action` owns the explicitly mutating install/apply/restart/publish and Git paths. Before any executable, command, HTTP request, or durable intent, the action tool flushes and replays the resolution/contract chain, then runtime authorization binds the action to one exact pending root-owned requirement/revision (never a prohibition or acceptance), rejects any matching pending root prohibition, and rechecks Guard integrity, host identity, semantic action, target-capture status, and every action-specific requested/resolved identity field. Exact package version/profile/registry and explicit Git remote/full refspec are required; resolution-only integrity, boot generation, and Git OIDs remain bound by the target digest and live prestate. `evidenceFromPersistedToolResult` maps persisted results to versioned semantic actions, evidence roles, exact resolved targets, observed state, executable identity, immutable resolution-time expected transition, and bounded diagnostics. Only exact adapter and command-manifest IDs/versions in the shipped manifests may supply structured state facts. On Windows, audited `.cmd`/`.bat` shims are version-probed through a closed invocation whose interpreter is pinned to the canonical `SystemRoot\\System32\\cmd.exe` realpath and version. Resolution and effect bind both identities; execution reuses the revalidated paths and rejects shell-control or expansion characters rather than re-resolving the logical name through `PATH` or trusting a changed `ComSpec`. Modify transition construction first re-hashes the current source bytes against the resolved pre-digest, then applies the pinned unique UTF-8 replacement. Commit readback parses the raw post-commit parent tuple and accepts exactly one parent equal to the resolved pre-effect HEAD; fetch freezes that HEAD and requires the post-effect HEAD to remain identical. Pre-execute revalidation is a correctness gate, not isolation from a concurrently malicious process running as the same user; a mismatching post-action readback remains non-certifiable.
5. `certifyCheckpoint` flushes and resynchronizes first. Non-stateful actions require an action-compatible minimal facet; every action in the ten-member `STATEFUL_ACTIONS` set requires distinct resolution, effect, and independent state evidence, one shared resolved target, non-overlapping state observations, and an expected-transition predicate frozen and digested by the resolution fact before effect. The binding must reproduce that payload exactly before observed state is compared.
6. A certificate freezes protocol/certificate versions, epoch, `sessionRefDigest`, `hostLockDigest`, contract revision/hash, explicit null-or-current Goal ref, open/evidence/binding digests, and the final certification digest. The tool computes a candidate without mutating runtime authority; only a persisted tool result that re-derives byte-for-byte becomes current authority.
7. `goalCompletionDenial` rejects the Guard-owned `update_goal(action=complete)` model-tool path before the Goal mutation unless that certificate is current. A trusted in-process producer can bypass the tool guard; replay detects the durable `goal/change complete` without a certificate and records an integrity violation, but the plugin does not claim to prevent or roll it back.
8. `context_guard_boundary` persists only qualified `user_wait`, `external_wait`, or `deferred` candidates. After the accepted tool result is flushed and replayed, the post-commit path reads the same active/armed Goal ref, calls `goals.disarm(agent)`, and independently reads the same ref as disarmed. Pre-effect, still-armed, and post-effect-unknown failures have separate fail-closed/fail-loud outcomes.
9. `decideTurnBoundary` reads only structured Guard/Goal state. Assistant completion prose is diagnostic and never a stop or continuation control source; active/armed continuation belongs to the Goal Round Driver.
10. `renderRecoveryPacket` re-injects open requirements after compaction, resume, enable, rejection, or integrity loss. Injection is content-deduplicated: a re-armed packet with unchanged content is injected once, while resume, compaction, an enablement transition, relevant new evidence, or a new contract revision changes or forgets the digest. Unrelated historical evidence does not re-arm the same guidance.

## 0.4.2 capture and rebinding

A legal plugin `user/message` notice marks the 0.4.2 capture boundary. Earlier events keep the 0.4.1 clause segmentation and visual classification; the runtime does not rewrite old source events, pending items, evidence IDs, or historical certificates. New compound requests separate explicitly named actions and retain GUI/visual acceptance as non-certifiable work. Updating a package and recording a change do not automatically mean installing or committing it.

`context_guard_rebind` accepts `operation: propose|query|withdraw`, `item_id`, `proposal_id`, `clauses`, and optional `clarification_item_ids`. It has no model confirmation flag. A proposal's 1–8 clauses must concatenate to the complete original normalized text, and its serialized body must fit 8 KiB. Each clarification ID is either empty (keep the source clause) or names a later pending direct-root item that explicitly includes that clause and preserves captured identities and method constraints. The proposal records both root sources, item/revision identities, session, epoch, contract revision, candidate action/target/acceptance, and a digest. A GUI clause cannot be mapped to an installation-only result.

The tool returns a candidate without mutating the projection. A matching durable tool result registers the proposal on replay. Replay validation is versioned: 0.5-era results match on structured semantic fields (status, reason code, proposal identity and digest) while display text may evolve; results carrying the frozen 0.4 response shapes validate byte-for-byte against the frozen 0.4 rules. Anything else is tampered or unknown and never replays.

A proposal that would keep every clause at `generic_run` when the original is already `generic_run` is refused as `no_certification_gain`: it would spend a user confirmation without improving certification. Partition mismatches return the bounded exact source (text, length, digest) instead of a generic error.

Since 0.5.0 a durable root message is one atomic confirmation transaction. The first non-empty top-level line may be the control line `确认重绑定 <proposal ID>`; the confirmation validates against the state BEFORE that message, and the remaining lines keep their own semantics — an explanation request stays conversational, a new task is captured like any other instruction, and an explicit reversal ("先不要确认") makes the whole message ambiguous and unapplied. A control string buried in a sentence, inside quotes, or inside a code block is malformed and never confirms; a matching control line that is not in first position, or two control lines, is ambiguous with no partial effect. Confirmation rechecks the proposal against the current contract; changed, withdrawn, cross-session, or non-durable inputs keep the old item pending, and a matching confirmation observed in a not-yet-durable log is reported as `not_durable` — distinguishable from one that was never sent. Every child is constructed before the original is marked superseded. `supersededByItems` preserves the one-to-many relation, and `reboundFrom` preserves the proposal and confirmation source. A later root clarification keeps its own authority; partitioning alone cannot authorize a new mutation. Duplicate confirmation is idempotent.

No digest-v3 wire format or upstream fixture changes are needed. A replacement changes the item/status set and contract revision, invalidating the earlier certificate; evidence is never copied into a passed state. A fresh checkpoint must revalidate the exact action, target, executor, host lock, and transition. Evidence predating the authoritative root clause referenced by a replacement is rejected while retaining its historical ID.

## 0.6.0 semantic layer

The v5 protocol boundary (`Context Guard protocol boundary: v5.0.0`), written
with the first real root-input step of a new session, activates the semantics
below. A session that never wrote it keeps the whole-session contract, version-1
certificates, and the frozen digest domains; a session that wrote it keeps
pre-boundary obligations under their birth rules while new work uses the v5
rules. `/context-guard migration` reports which of the two is in force.

| Module | Owns |
| --- | --- |
| `domain/spans.ts` | UTF-8 byte offsets and half-open spans of the original root text |
| `domain/host-selection.ts` | Trusted question round-trips; a selection is only ever a paired call + result |
| `domain/work-unit.ts` | Derived units, delegation lineage, ancestor/descendant relations, explicit switch and delegation vocabularies |
| `domain/closure.ts` | The single open-closure implementation: visible pending, certifiable open, unit closure with required descendants, and the ancestor constraints in force |
| `domain/delivery.ts` | Trusted answer delivery: the four-part composition criterion over durable turn structure |
| `domain/proof.ts` | v1 and v2 proof manifests, the v2 capability matrix, and the binding/refusal rules per kind |
| `domain/release.ts` | Explicit release contracts, one-shot reservations, readback settlements, coverage surface, and the pre-effect gate |
| `domain/reason-class.ts` | The frozen seven-class mapping for every reason code |
| `domain/migration.ts` | Rule set in force, preserved identities, and the rollback precondition |
| `domain/diagnostics.ts` | Historical and explicit-certificate per-item diagnosis, including its reason class; default v6 ordinary feedback reads the confirmed core through `domain/v6-feedback.ts` |

### Delivery

A delivery fact exists only when the host's own log says so: an
`assistant/message` for turn T at that turn's highest step, with no
`interrupted` marker, followed by `turn/end { turn: T, reason.kind:
"completed" }`. `assistant/attempt` records, aborted or errored turns, other
turns' replies, and delegated sessions never bind a delivery. Delivery closes
only information-slot obligations captured inside that turn (including those of
a delegated sub-unit created in it), and it proves delivery only — never
accuracy, sufficiency, or execution.

### Units and closure

Units are derived from the durable message stream, never written. A
delegation-marked root message opens a CHILD unit: the parent stays the current
unit, so delegating a sub-task cannot drop the parent's own work, and the
child's open obligations join the parent's closure as required descendants. An
ordinary task switch opens a sibling, whose residual work deliberately does not
block the newer task. A delegated tool round-trip is recorded per unit and its
evidence is marked bounded, so a subagent's result is visible and auditable but
can never close a parent obligation. Certifying a unit also refuses any binding
that an ancestor unit's prohibition or unsatisfied condition still governs.

### Proof v2

The v1 manifest and `ccg.proofManifest.v1` are frozen and read by their own
rules. The v2 manifest (`0.6.0`, `ccg.proofManifest.v2`) binds each obligation
to a current subject, a declared source, and a real operation, and covers eight
kinds. Tool success is only ever an `execution_fact`; a visual readback needs a
fact that carries a visual-readback capability and actually read the subject; an
input asset check must be a prior-state fact; an external fact needs a completed
external-operation reference; and a cohort with no producer reports
`proof_producer_capability_unavailable`. Strict policy uses this same matrix to
demand the proof the user explicitly asked for.

### Explicit release

Release adoption remains a root `command/run`. Reservations, settlements, and
restart intents use an owner-only append-only private ledger beneath the DSH
home selected by the host's non-empty `DSH_HOME` or default `~/.dsh`. The
ledger anchors a hashed Session header, cwd, host lock, and canonical ledger
root; release rows additionally bind the immutable adopted contract, resolved
target, and preceding reservation. Each row is hash-chained and carries a
private-ledger position rather than pretending to be a Session sequence.
Reservations are flushed before the effect and record
the SRI the trusted producer read; a settlement records a trusted readback when
one exists and otherwise remains non-settling (`unknown` or `unconfirmed`), which preserves the in-flight
protection and refuses a re-send. Missing, truncated, cross-session, mismatched,
or locked ledger state fails closed. Historical plugin-notice records remain
readable under their frozen rules but are not migrated into stronger sidecar
facts. `release status`/`release revoke` are read-only and
authority-withdrawing respectively — neither is a state corruption.

The contract freezes the candidate scope's `adoptedAtRevision`, and the closure
certificate must be the one that certified exactly that revision: the release
instruction is itself a new obligation, so requiring the CURRENT revision would
make publishing depend on having already published, while freezing the revision
still refuses a candidate whose content moved on.

Candidate identity is read from trusted producers only: the action tool reads
the exact tgz (byte SHA-256, npm SRI, embedded `gitHead`, package, version,
repository) and the canonicalized registry, and the runtime resolves a declared
ref with the audited git executable. Each named identity is compared with its
own observation.

`context_guard_release` is the recovery entry: `status` is a read-only report,
and `reconcile` reads the external identity through the auditing registry
adapter and settles a reservation only when the readback names the frozen bytes.
It never re-sends a release, and it works after a restart and for a
revoked-but-in-flight attempt. `RuntimeExecutorSeams` exists so an acceptance
run can replace the mutation executor, the HTTP client and the pinned host
cohort; the release gate, records, producers and replay stay production code.

## Bounded queries and recovery

Checkpoint certification runs over the complete contract before display filtering. Default pages contain at most eight current items/constraints and ten evidence rows. Each list has its own cursor, bound to the session, epoch, contract revision, query, bindings, and evidence snapshot. `history` includes unsupported evidence with an unavailable disposition; default evidence and binding templates share action/target matching. Unknown cursor state is an explicit query error.

The serializer reserves metadata space before selecting rows and returns at most 12 KiB of valid UTF-8 JSON. Oversized rows identify omitted detail; `detail_id` retrieves bounded JSON-text chunks. Later chunks require the initial `snapshot` as `detail_snapshot`. A long ID may use a SHA-256 lookup token in the summary; its original ID remains unchanged in the detail. Explicit `item_ids` can inspect passed and superseded provenance as well as current work. None of these views changes the certificate's scope.

Recovery reserves its rules, query pointer and folding totals before filling item summaries. Separate category slots retain a key prohibition and the newest pending requirement before optional rejection details or evidence; many constraints cannot hide the current work. Long IDs are summarized independently of the reason and next step. Small packets distinguish capability restoration from requirement rebinding. Its default budget is 4,000 characters; values below 512 or non-integers are rejected. The 512-character form keeps a constraint, the current limitation, and a query pointer. Full constraint enforcement remains in the ledger and execution checks. The runtime re-derives binding refusals from persisted calls and deduplicates guidance against the current contract and relevant evidence. A real compact/resume boundary always resets that context-local deduplication.

### Session initial activation (0.9.0)

The real Cordis schema preserves omitted activation; qualified public startup binds only fresh unseeded roots. Existing sessions read their write-once birth binding, and pre-upgrade sessions need independent inventory/adoption. Resume, compact, clear and late attach cannot guess a mode. Every sync freshly calls `readActivationBinding`; missing/changed/conflicting files invalidate fast paths and certification. This store is independent of the certificate identity and private release ledger, with no global birth WAL or mode transaction. Exact parent cut comes from the host contract; no factory issuer token is assumed. See [storage, migration and Windows capability limits](ACTIVATION_MIGRATION.md).

真实 Cordis schema 保留省略来源，合格 startup 只绑定新建无继承根。旧会话读取不可覆盖出生绑定，升级前库存需独立 adoption；恢复等入口不猜模式。每次 sync 新鲜读取绑定，缺失、变化、冲突使缓存及认证失效。存储独立于证书身份和私有发布账本，无全局 birth WAL 或模式事务。父 cut 来自宿主合同，不假设 issuer token；平台能力边界见迁移说明。
