dsh-completion-guard 0.4.3 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,7 +53,125 @@ declare function requestedTargetMatchesResolved(action: StatefulAction, requeste
53
53
  declare function requestedTargetAuthorizesMutation(action: StatefulAction, requested: TargetTuple | undefined, resolved: TargetTuple | undefined): boolean;
54
54
  declare function validateActionManifest(): string[];
55
55
  //#endregion
56
+ //#region src/domain/semantics.d.ts
57
+ /**
58
+ * The single interpretation of a root-user instruction.
59
+ *
60
+ * Before 0.5.1, capture, mutation authorization and boundary qualification each
61
+ * re-guessed what one sentence meant, and the guesses disagreed: the incident
62
+ * instruction "按 P0—P4 完成本地实现、测试和文档,在跨平台验证前停止,不推送、
63
+ * 不正式发布。" was captured as a *push* obligation, so the only certifiable item
64
+ * demanded the very action its own text forbade.
65
+ *
66
+ * This module answers the question once. It partitions the message into
67
+ * semantic scopes first, then reads the action inside each scope, so:
68
+ *
69
+ * 1. a prohibition's scope covers every coordinated action it governs, and a
70
+ * prohibition constrains execution instead of creating an obligation to
71
+ * perform the forbidden action;
72
+ * 2. only an explicit, agent-owned, unconditional directive becomes an
73
+ * immediately executable duty — naming an action is not authorizing it;
74
+ * 3. a conditional directive stays unexecuted until its condition holds, and a
75
+ * human-owned action never becomes agent work;
76
+ * 4. quotation and code keep an action visible but never grant authority;
77
+ * 5. an interpretation that cannot be resolved reads conservatively and is not
78
+ * executed.
79
+ *
80
+ * No rule here keys on a session id, an event sequence, a file name, or a fixed
81
+ * phrase list for one incident sentence: the rules are polarity, scope,
82
+ * executee and condition, so paraphrases, mixed languages, word-order changes
83
+ * and punctuation changes agree with the original.
84
+ */
85
+ /**
86
+ * How one message is read.
87
+ *
88
+ * `coordinationSplit` is the one historical granularity switch: a message
89
+ * captured before the 0.4.2 capture boundary keeps a coordinated action in one
90
+ * clause, exactly as that release recorded it. Every semantic rule (polarity,
91
+ * executee, condition, quotation) applies identically in both modes, so replay
92
+ * stability never depends on re-reading an older message with newer semantics.
93
+ */
94
+ interface InterpretOptions {
95
+ coordinationSplit?: boolean;
96
+ }
97
+ /** What one scope does with the action it names. */
98
+ type DirectiveClass = "directive" | "prohibition" | "conditional" | "informational" | "narrative";
99
+ /** Who is expected to perform the action. */
100
+ type Executee = "agent" | "user" | "unresolved";
101
+ /** How the scope's authority reads. */
102
+ type AuthorityDisposition = "executable_now" | "conditional_wait" | "human_actor" | "informational" | "prohibition" | "unresolved";
103
+ interface ScopeInterpretation {
104
+ /** Verbatim scope text, trimmed: the audit record of what was read. */
105
+ text: string;
106
+ /** The action-bearing text with leading connectors and negators removed. */
107
+ body: string;
108
+ directive: DirectiveClass;
109
+ executee: Executee;
110
+ /** The unresolved condition that must hold before the action may run. */
111
+ condition?: string;
112
+ /** The event that ends a human wait, when the source names one. */
113
+ resumeEvent?: string;
114
+ /** True only for an explicit, agent-owned, unconditional instruction. */
115
+ immediatelyExecutable: boolean;
116
+ authorityDisposition: AuthorityDisposition;
117
+ /** Explicitly named tool/method, when the scope names one. */
118
+ method?: string;
119
+ /** Stable identity of this interpretation, reproducible from the same bytes. */
120
+ fingerprint: string;
121
+ }
122
+ /**
123
+ * The contract kind a scope maps to. A prohibition and an acceptance keep their
124
+ * own lanes; everything else is a requirement. Acceptance is decided from the
125
+ * clause's own head verb, so "确保构建通过" stays an acceptance while a
126
+ * conditional or prohibition clause is never mislabelled.
127
+ */
128
+ declare function kindOfScope(directive: DirectiveClass, body?: string): GuardItemKind;
129
+ declare function maskCodeSpans(text: string): string;
130
+ /** Interpret one already-segmented clause. */
131
+ declare function interpretClause(text: string, options?: InterpretOptions): ScopeInterpretation;
132
+ /** Interpret a whole message into independent scopes, in source order. */
133
+ declare function interpretMessage(text: string, options?: InterpretOptions): ScopeInterpretation[];
134
+ /**
135
+ * Whether the item is an executable obligation right now. A prohibition is a
136
+ * standing constraint, a human-owned action belongs to the user, a conditional
137
+ * action waits for its condition, and an explanation is not work. None of them
138
+ * may block completion or be certified as agent work.
139
+ *
140
+ * An item without an interpretation is a legacy or fixture item created before
141
+ * this module existed; it keeps its historical executable reading.
142
+ */
143
+ declare function isExecutableItem(item: {
144
+ kind?: string;
145
+ executee?: Executee;
146
+ authorityDisposition?: AuthorityDisposition;
147
+ waitAuthorization?: unknown;
148
+ }): boolean;
149
+ /** Whether an item is an open obligation for certification purposes. */
150
+ declare function isOpenObligation(item: GuardItem): boolean;
151
+ /**
152
+ * The action a scope names. `semanticActionFromText` maps the command surface,
153
+ * but a prohibition keeps a bare verb as its body ("不要提交并推送" → 提交并推送),
154
+ * and the closed CJK vocabulary is consulted first so such a ban is still
155
+ * recorded against the action it forbids.
156
+ */
157
+ declare function semanticActionOfScope(body: string, source?: string, isProhibition?: boolean): ReturnType<typeof semanticActionFromText>;
158
+ /**
159
+ * Every stateful action the clause names, in source order. A clause may order
160
+ * more than one ("安装插件,重启 DSH"); each is a separate evidence obligation
161
+ * even though the clause stays one top-level item.
162
+ */
163
+ declare function statefulActionsOfScope(body: string): StatefulAction[];
164
+ /** Actions this interpretation names, in source order (diagnostics only). */
165
+ declare function namedActions(text: string): string[];
166
+ //#endregion
56
167
  //#region src/domain/rebind.d.ts
168
+ interface RebindArgs {
169
+ operation: "propose" | "query" | "withdraw";
170
+ item_id?: string;
171
+ proposal_id?: string;
172
+ clauses?: string[];
173
+ clarification_item_ids?: string[];
174
+ }
57
175
  interface RebindProposal {
58
176
  id: string;
59
177
  digest: string;
@@ -78,7 +196,56 @@ interface RebindProposal {
78
196
  status: "pending" | "confirmed" | "withdrawn" | "stale";
79
197
  confirmationEvent?: string;
80
198
  replacementIds?: string[];
81
- }
199
+ /** Proposals created under the 0.5 protocol carry their replay schema. */
200
+ protocol?: "v050";
201
+ /** Matching control line observed during a non-durable replay (not applied). */
202
+ observedUnconfirmedEvent?: string;
203
+ }
204
+ /** Bounded alignment facts for a mismatched partition, budget-aware. */
205
+ interface BoundedSource {
206
+ length: number;
207
+ sha256: string;
208
+ text?: string;
209
+ head?: string;
210
+ tail?: string;
211
+ }
212
+ /** Typed propose outcomes; `undefined` never hides WHY a proposal failed. */
213
+ type ProposeOutcome = {
214
+ ok: true;
215
+ proposal: RebindProposal;
216
+ } | {
217
+ ok: false;
218
+ reasonCode: "item_not_found" | "item_not_pending" | "unsupported_clarification" | "partition_mismatch" | "payload_too_large" | "no_certification_gain";
219
+ /** Bounded alignment facts for partition mismatches, within the 12 KiB budget. */
220
+ source?: BoundedSource;
221
+ };
222
+ /** Exact source partition is deliberately conservative: a proposal cannot
223
+ * invent authority or silently discard a difficult acceptance clause. */
224
+ declare function proposeRebind(p: GuardProjection, args: RebindArgs): RebindProposal | undefined;
225
+ /** 0.5 proposer with typed failures and the no-certification-gain gate. */
226
+ declare function proposeRebindOutcome(p: GuardProjection, args: RebindArgs): ProposeOutcome;
227
+ /**
228
+ * Frozen v0.4.2/v0.4.3 proposer: identical semantics to the 0.4 releases,
229
+ * without the 0.5 no-gain gate or typed failures. Used ONLY to replay
230
+ * historical tool results and historical confirmations faithfully.
231
+ */
232
+ declare function proposeRebindV042(p: GuardProjection, args: RebindArgs): RebindProposal | undefined;
233
+ /** Stable attempt key: item identity, exact inputs, and outcome class. Identical
234
+ * retries collapse onto it no matter how many unrelated log rows intervene. */
235
+ declare function rebindAttemptKey(p: GuardProjection, args: RebindArgs, reasonCode: string): string;
236
+ declare function rebindResponse(p: GuardProjection, args: RebindArgs): Record<string, unknown>;
237
+ /**
238
+ * Replay validation with version dispatch (A12): structured v0.5 results
239
+ * match semantically (display text may evolve); results carrying the frozen
240
+ * 0.4 response shapes validate against the frozen 0.4 rules exactly. Anything
241
+ * else is tampered or unknown and never replays.
242
+ */
243
+ declare function replayRebindResult(p: GuardProjection, args: RebindArgs, recorded: Record<string, unknown>): void;
244
+ /** Invoked only for a canonical root user message, never tool or plugin text.
245
+ * The single durable confirmation event is the atomic transaction commit:
246
+ * the confirmation validates against the state BEFORE this message, and the
247
+ * caller processes the remaining text afterwards with its own semantics. */
248
+ declare function confirmRebind(p: GuardProjection, proposalId: string, eventId: string, durable: boolean): boolean;
82
249
  //#endregion
83
250
  //#region src/domain/digest.d.ts
84
251
  type TypedObject = {
@@ -87,10 +254,32 @@ type TypedObject = {
87
254
  };
88
255
  type Typed = boolean | number | string | TypedObject;
89
256
  interface SessionHeader {
257
+ /**
258
+ * DSH Session format version stamped into the durable header. Guard supports
259
+ * only the V3 session format (`3`); any other value is a different digest
260
+ * domain input rather than being reinterpreted as V3.
261
+ */
90
262
  version: number;
91
263
  id: string;
92
264
  createdAt: number;
93
265
  parentSession?: string;
266
+ /**
267
+ * Durable fork-inherited prefix length.
268
+ *
269
+ * DSH Session V3 moved this value out of the header onto the `Session`
270
+ * itself as `inheritedEventCount` (durably marked by `session/end-seed`); the
271
+ * meaning is unchanged, so the token keeps its historical name and the `v3`
272
+ * digest domain keeps every byte-mirrored vector identical.
273
+ *
274
+ * V3's `header.isSeeded` marker is deliberately NOT added as a digest input.
275
+ * It is not needed for identity — `parentSession`, `seedLength`,
276
+ * `delegationDepth` and `origin` already bind the fork lineage, and `id` plus
277
+ * `createdAt` separate distinct sessions — while adding any field (even an
278
+ * optional one) would change every existing digest, because an absent
279
+ * optional field still encodes a presence-0 row. Changing the shared digest
280
+ * domain is an upstream semantic decision with its own cross-repository
281
+ * parity gate; a host upgrade must not make it silently.
282
+ */
94
283
  seedLength?: number;
95
284
  agentPreset?: string;
96
285
  origin?: string;
@@ -173,6 +362,36 @@ interface GuardItem {
173
362
  targetCaptureReasonCode?: TargetCaptureReasonCode;
174
363
  authority?: "root_instruction" | "root_adoption" | "legacy_authority_unclassified";
175
364
  legacyFlags?: Array<"legacy_generic_run" | "legacy_authority_unclassified">;
365
+ /** v0.5 intent layer: inquiries keep the obligation but are not machine certifiable. */
366
+ taskKind?: "inquiry" | "action";
367
+ /**
368
+ * v0.5.1 interpretation layer, derived from the same source bytes as
369
+ * {@link normalizedText} by `domain/semantics.ts`. These fields record what
370
+ * the message actually authorized, so a prohibition, a human-owned action, a
371
+ * conditional action and an explanation can never become an agent obligation.
372
+ * Absent on legacy items, which keep their historical executable reading.
373
+ */
374
+ directive?: DirectiveClass;
375
+ executee?: Executee;
376
+ authorityDisposition?: AuthorityDisposition;
377
+ /** The unresolved condition guarding a `conditional_wait` item. */
378
+ condition?: string;
379
+ /** The event that ends a human wait, when the source names one. */
380
+ resumeEvent?: string;
381
+ /** Stable identity of the interpretation these fields came from. */
382
+ interpretationFingerprint?: string;
383
+ /**
384
+ * Every stateful action this item's clause names, in source order, with the
385
+ * target captured for each. A clause may order more than one action
386
+ * ("安装插件,重启 DSH"): the item stays one top-level obligation, and every
387
+ * action it names needs its own matching evidence before it can close.
388
+ */
389
+ actionPlan?: Array<{
390
+ action: "install" | "apply" | "create" | "modify" | "restart" | "commit" | "push" | "publish" | "pull" | "fetch";
391
+ requestedTarget: TargetTuple;
392
+ targetCaptureStatus: TargetCaptureStatus;
393
+ targetCaptureReasonCode?: TargetCaptureReasonCode;
394
+ }>;
176
395
  waitAuthorization?: WaitAuthorization;
177
396
  deferAuthorization?: DeferAuthorization;
178
397
  persistenceAuthorization?: PersistenceAuthorization;
@@ -232,6 +451,20 @@ interface EvidenceBinding {
232
451
  resolutionEvidenceId?: string;
233
452
  effectEvidenceId?: string;
234
453
  stateEvidenceIds?: string[];
454
+ /**
455
+ * Per-action closure for a clause that ordered several actions. Every entry
456
+ * of {@link GuardItem.actionPlan} needs its own entry here: one action's
457
+ * evidence never covers another action, and two instances of the same action
458
+ * on different targets are two separate entries.
459
+ */
460
+ actionBindings?: BindingActionClosure[];
461
+ }
462
+ interface BindingActionClosure {
463
+ action: StatefulAction;
464
+ evidenceIds: string[];
465
+ resolvedTarget: TargetTuple;
466
+ /** Position of this action in the clause's instruction order. */
467
+ order: number;
235
468
  }
236
469
  interface GuardCheckpoint {
237
470
  id: string;
@@ -250,8 +483,8 @@ interface GuardCheckpoint {
250
483
  certificationDigest: string;
251
484
  result: "certified" | "incomplete" | "unknown";
252
485
  }
253
- type BoundaryDisposition = "user_wait" | "external_wait" | "deferred";
254
- type BoundaryQualificationKind = "user_decision_item" | "root_explicit_wait" | "external_operation_pending" | "root_explicit_defer";
486
+ type BoundaryDisposition = "user_wait" | "external_wait" | "deferred" | "guard_bounded_stop";
487
+ type BoundaryQualificationKind = "user_decision_item" | "root_explicit_wait" | "external_operation_pending" | "root_explicit_defer" | "guard_no_progress";
255
488
  interface GuardBoundary {
256
489
  protocolVersion: "1";
257
490
  id: string;
@@ -304,9 +537,43 @@ interface GuardProjection {
304
537
  offendingEvidenceIds?: string[];
305
538
  }>;
306
539
  lastCheckpointRejectionRevision?: number;
540
+ /** Bounded fact about the latest rejected confirmation attempt (never raw text). */
541
+ lastConfirmationRejection?: {
542
+ eventSeq: number;
543
+ kind: "malformed" | "ambiguous";
544
+ reason: string;
545
+ };
307
546
  continuationAttempts: Map<number, number>;
308
547
  /** Process-local one-shot fallback counters keyed by epoch + contract revision. */
309
548
  persistenceCorrectionAttempts: Map<string, number>;
549
+ /**
550
+ * The no-progress budget, rebuilt from the durable log.
551
+ *
552
+ * Keyed by progress fingerprint, then by the boundary the claim was decided
553
+ * at, holding the attempt number that boundary was given. Keyed by boundary
554
+ * rather than counted per fingerprint on purpose: the same boundary processed
555
+ * twice — a retry, with or without the projection being re-derived in between
556
+ * — maps to the same key and therefore the same attempt, so a retry cannot
557
+ * spend the budget twice, while a genuinely new boundary adds a new key.
558
+ */
559
+ noProgressClaims: Map<string, Map<string, number>>;
560
+ /**
561
+ * Root event sequences whose control request Guard already carried to the
562
+ * host. A pause is a one-shot input: once the host has paused, the same
563
+ * message stays in the log forever, and re-reading it must not re-pause a goal
564
+ * the human has since resumed.
565
+ */
566
+ handledControlSeqs: Set<number>;
567
+ /**
568
+ * The host turn the projection is currently in, taken from the host's own
569
+ * durable `turn/start` event. This is the turn boundary's identity: the host
570
+ * opens it before it claims input or runs pre-step, so it is stable across a
571
+ * reload, it does not move when Guard writes its own bookkeeping, and a retry
572
+ * of the same turn re-reads the same number.
573
+ */
574
+ hostTurn?: number;
575
+ /** Log-derived count of rejected rebind attempts by stable attempt key; survives reload. */
576
+ rebindRejections: Map<string, number>;
310
577
  integrity: GuardIntegrity;
311
578
  }
312
579
  declare function createProjection(): GuardProjection;
@@ -326,6 +593,10 @@ interface DeriveResult {
326
593
  enablementTransitioned: boolean;
327
594
  /** Sequence of the last compaction summary in the log, or -1 when none. */
328
595
  lastCompactionSeq: number;
596
+ /** True when a real root user input (text or asset) is present while enabled. */
597
+ realRootInputSeen: boolean;
598
+ /** True when the durable log carries the 0.5 first-step protocol boundary. */
599
+ protocolV4Present: boolean;
329
600
  }
330
601
  interface DerivedEnvelope {
331
602
  seq: number;
@@ -381,11 +652,12 @@ interface BoundaryEffectuation {
381
652
  declare function effectuateBoundary(boundary: GuardBoundary, access: GoalBoundaryAccess): Promise<BoundaryEffectuation>;
382
653
  //#endregion
383
654
  //#region src/domain/capture.d.ts
384
- interface ClassifiedClause {
385
- kind: GuardItemKind;
386
- body: string;
387
- }
388
- declare function classifyClause(text: string): ClassifiedClause;
655
+ /**
656
+ * Whether a clause opens with an explicit ban. The lane question ("is this a
657
+ * constraint or a duty?") is answered by {@link ScopeInterpretation}; this stays
658
+ * exported because the framing/segmentation callers ask it directly.
659
+ */
660
+ declare function classifyClause(text: string): GuardItemKind;
389
661
  /**
390
662
  * Detect an explicitly named tool/method in a clause ("使用 bash 创建",
391
663
  * "via bash", "bash to create"). Returns the canonical tool id (e.g. 'bash')
@@ -415,27 +687,40 @@ interface CaptureScope {
415
687
  declare function extractArtifactPaths(text: string): string[];
416
688
  /**
417
689
  * Split a single human message into independently tracked clauses. Sentence
418
- * boundaries and embedded prohibition keywords delimit segments so a compound
419
- * instruction such as "Modify src/a.ts and src/b.ts. Do not push." yields
420
- * separate items instead of collapsing into one artifact.
690
+ * boundaries and negations delimit segments so a compound instruction such as
691
+ * "Modify src/a.ts and src/b.ts. Do not push." yields separate items instead of
692
+ * collapsing into one artifact.
693
+ *
694
+ * Segmentation asks {@link interpretMessage} where the semantic scopes are, so a
695
+ * negation keeps its whole coordinated span ("不推送、不发布" is two
696
+ * prohibitions, not one requirement) and a mixed sentence keeps both executees.
421
697
  */
422
698
  interface ClauseSegment {
423
699
  kind: GuardItemKind;
700
+ /** Action-bearing text used for target, method and operation extraction. */
424
701
  body: string;
702
+ /** Verbatim source scope, kept for the audit record. */
703
+ text: string;
425
704
  paths: string[];
705
+ /** The one interpretation this segment came from; never re-derived downstream. */
706
+ interpretation: ScopeInterpretation;
426
707
  }
427
- declare function segmentClauses(text: string, captureVersion?: "v041" | "v042"): ClauseSegment[];
708
+ declare function segmentClauses(text: string, options?: InterpretOptions): ClauseSegment[];
428
709
  /**
429
710
  * Build a GuardItem from an already-classified clause body and a resolved
430
711
  * verification subject/surface.
712
+ *
713
+ * The optional `interpretation` carries the scope reading taken from the same
714
+ * bytes. It is passed through rather than re-derived, so the obligation lane and
715
+ * the authority of one clause cannot disagree between callers.
431
716
  */
432
- declare function captureItem(kind: GuardItemKind, body: string, sourceMessageId: string, id: string, revision: number, subject: string, surface: "artifact" | "scope", method?: string, operation?: GuardOperation, captureVersion?: "v041" | "v042"): GuardItem;
717
+ declare function captureItem(kind: GuardItemKind, body: string, sourceMessageId: string, id: string, revision: number, subject: string, surface: "artifact" | "scope", method?: string, operation?: GuardOperation, interpretation?: ScopeInterpretation): GuardItem;
433
718
  /**
434
719
  * Capture one contract clause. Every captured item receives a concrete
435
720
  * verification contract: a named artifact path (artifact surface) or the
436
721
  * session scope (scope surface), so an unrelated file read can never close it.
437
722
  */
438
- declare function captureClause(text: string, sourceMessageId: string, id: string, revision: number, scope?: CaptureScope): GuardItem;
723
+ declare function captureClause(text: string, sourceMessageId: string, id: string, revision: number, scope?: CaptureScope, options?: InterpretOptions): GuardItem;
439
724
  //#endregion
440
725
  //#region src/domain/checkpoint.d.ts
441
726
  interface RejectedBinding {
@@ -454,6 +739,41 @@ interface CheckpointResult {
454
739
  }
455
740
  declare function certifyCheckpoint(projection: GuardProjection, bindings: EvidenceBinding[], id: string, commit?: boolean): CheckpointResult;
456
741
  //#endregion
742
+ //#region src/domain/confirm-parse.d.ts
743
+ /**
744
+ * 0.5 confirmation-line grammar (A10/A11).
745
+ *
746
+ * A durable root message may carry AT MOST ONE rebind confirmation as a
747
+ * restricted top-level control line; everything after it is follow-up content
748
+ * processed with its own semantics. The parser is intentionally conservative:
749
+ * - only the first non-empty top-level line can be a control line;
750
+ * - lines inside code fences, quoted lines, and blockquote/forward wrappers
751
+ * are data, never control;
752
+ * - an embedded or mid-sentence control string is `malformed`, never a
753
+ * confirmation;
754
+ * - a matching control line that is NOT in first position, or an explicit
755
+ * reversal in the remainder, makes the whole message `ambiguous` (stays
756
+ * unconfirmed; no partial effect).
757
+ */
758
+ type ParsedConfirmation = {
759
+ kind: "none";
760
+ } | {
761
+ kind: "malformed";
762
+ reason: "embedded_control_text" | "inside_code_fence" | "quoted";
763
+ } | {
764
+ kind: "ambiguous";
765
+ reason: "multiple_control_lines" | "late_control_line" | "reversal_in_remainder";
766
+ } | {
767
+ kind: "confirm";
768
+ proposalId: string;
769
+ remainder: string;
770
+ };
771
+ declare const CONFIRM_LINE_PATTERN: RegExp;
772
+ /** Parse control without rewriting the follow-up's authority wrappers. */
773
+ declare function parseConfirmationMessage(text: string): ParsedConfirmation;
774
+ /** Whether a recorded tool/result carries the frozen v0.4.x response shape. */
775
+ declare function isFrozenV042RebindResponse(recorded: unknown): boolean;
776
+ //#endregion
457
777
  //#region src/domain/conversation.d.ts
458
778
  type UserInteractionKind = "instruction" | "conversational";
459
779
  /**
@@ -469,6 +789,15 @@ type UserInteractionKind = "instruction" | "conversational";
469
789
  * forms, and finally a progression lead over a featureless remainder.
470
790
  */
471
791
  declare function classifyUserInteraction(text: string): UserInteractionKind;
792
+ type TaskIntent = "inquiry" | "action";
793
+ /**
794
+ * Separate intent layer (v0.5): whether the captured work is an inquiry about
795
+ * state or an ordered change. Intent NEVER drops capture or weakens
796
+ * protection — an inquiry keeps its original obligation; it only changes what
797
+ * certification support the diagnosis reports (inquiries are not machine
798
+ * certifiable by the current adapters and must not be re-bound).
799
+ */
800
+ declare function classifyTaskIntent(text: string): TaskIntent;
472
801
  //#endregion
473
802
  //#region src/domain/contract-segment.d.ts
474
803
  type AuthorityBlockKind = "instruction" | "reference" | "quoted" | "code" | "uncertain";
@@ -494,10 +823,91 @@ declare function authorityCaptureCounts(blocks: readonly AuthorityBlock[]): Reco
494
823
  /** One authoritative contract identity shared by checkpoints and boundaries. */
495
824
  declare function currentContractDigest(projection: GuardProjection): string;
496
825
  //#endregion
826
+ //#region src/domain/host-version.d.ts
827
+ /**
828
+ * DSH host version support policy.
829
+ *
830
+ * Context Guard 0.5.1 supports **DSH >= 0.1.5-rc.1** and nothing older. The
831
+ * policy is one value with one comparison, used by the install entry
832
+ * (`peerDependencies`), by the runtime host readback, and by the decision tests
833
+ * — so the advertised range and the enforced range cannot drift apart.
834
+ *
835
+ * ## Why a range is not enough on its own
836
+ *
837
+ * npm's SemVer prerelease rule is narrower than "0.1.5-rc.1 or newer": a
838
+ * version carrying a prerelease satisfies a comparator set only when some
839
+ * comparator in that set names the SAME `major.minor.patch` tuple and itself
840
+ * carries a prerelease. For the range `>=0.1.5-rc.1` that means:
841
+ *
842
+ * | Candidate | Satisfies `>=0.1.5-rc.1` | Why |
843
+ * | --- | --- | --- |
844
+ * | `0.1.5-rc.1` | yes | the bound itself |
845
+ * | `0.1.5-rc.2` | yes | same tuple, comparator has a prerelease |
846
+ * | `0.1.5` | yes | a release is ordered after its own prereleases |
847
+ * | `0.1.6`, `0.2.0` | yes | higher release |
848
+ * | `0.1.6-rc.1` | **no** | prerelease of a DIFFERENT tuple |
849
+ * | `0.2.0-rc.1` | **no** | prerelease of a DIFFERENT tuple |
850
+ * | `0.1.4`, `0.1.5-alpha.9` | no | below the bound |
851
+ *
852
+ * No finite SemVer range expresses "every future prerelease at any base", and
853
+ * an unconditional `*` would drop the lower bound entirely. The range is
854
+ * therefore the honest, conservative install-time statement, and this module is
855
+ * the explicit runtime/decision path for the policy itself: {@link
856
+ * compareHostVersions} accepts a future different-base RC by the documented
857
+ * policy while {@link evaluateMinimumHostVersion} still refuses anything below
858
+ * the minimum. An unobserved new-base RC remains `unverified` for host-lock
859
+ * purposes — the version policy never substitutes for the exact-graph host
860
+ * audit.
861
+ */
862
+ /** Lowest supported DSH host version. DSH packages version independently of Cordis. */
863
+ declare const MIN_SUPPORTED_HOST_VERSION = "0.1.5-rc.1";
864
+ /**
865
+ * The exact npm range published in `peerDependencies`. It is deliberately the
866
+ * plain lower bound plus the documented prerelease caveat above.
867
+ */
868
+ declare const SUPPORTED_HOST_RANGE: string;
869
+ interface ParsedHostVersion {
870
+ major: number;
871
+ minor: number;
872
+ patch: number;
873
+ /** Dot-separated prerelease identifiers; empty for a release version. */
874
+ prerelease: readonly string[];
875
+ }
876
+ declare function parseHostVersion(value: string): ParsedHostVersion | undefined;
877
+ /**
878
+ * SemVer precedence comparison, including the prerelease rules. Returns
879
+ * `undefined` for a value that is not a version this module can order, so an
880
+ * unparseable host version fails closed rather than sorting as "newer".
881
+ */
882
+ declare function compareHostVersions(a: string, b: string): number | undefined;
883
+ type HostVersionStatus = "supported" | "below_minimum" | "unparseable";
884
+ interface HostVersionDecision {
885
+ status: HostVersionStatus;
886
+ version: string;
887
+ minimum: string;
888
+ reasonCode: "host_version_supported" | "host_version_below_minimum" | "host_version_unparseable";
889
+ }
890
+ /** Decide the version-policy half of host support. Never a substitute for the graph lock. */
891
+ declare function evaluateMinimumHostVersion(version: string, minimum?: string): HostVersionDecision;
892
+ /**
893
+ * Whether npm's own range resolution would admit this version for
894
+ * {@link SUPPORTED_HOST_RANGE}. Used by the decision tests to keep the
895
+ * documented prerelease table true, and by diagnostics to explain why an
896
+ * install did not resolve.
897
+ */
898
+ declare function satisfiesSupportedHostRange(version: string): boolean;
899
+ //#endregion
497
900
  //#region src/domain/host-lock.d.ts
498
901
  type HostLockStatus = "supported" | "unsupported" | "unavailable";
499
902
  type HostPlatform = "posix" | "windows";
500
903
  type HostProfileKind = "headless" | "web";
904
+ /**
905
+ * How a cohort's package rows were established. Bound into every host-lock
906
+ * digest through the `host_audit_provenance` capability row, so a certificate
907
+ * records whether the exact graph it used was loaded on a native host or only
908
+ * resolved from the registry.
909
+ */
910
+ type HostAuditProvenance = "native-audited" | "registry-derived-pending-native-audit";
501
911
  interface HostCohort {
502
912
  /** Stable cohort identity; bound into every hostLockDigest via `host_cohort`. */
503
913
  id: string;
@@ -505,10 +915,19 @@ interface HostCohort {
505
915
  supportedGoalVersions: string[];
506
916
  /**
507
917
  * Platforms where this cohort's exact package graph was extracted from a
508
- * native host and audited. Other platforms fail closed; integrity must not
509
- * be inferred across platforms.
918
+ * native host and audited. A cohort with no native audit has an empty list
919
+ * here even while it accepts evaluations — see {@link acceptedPlatforms}.
510
920
  */
511
921
  auditedPlatforms: readonly HostPlatform[];
922
+ /**
923
+ * Platforms on which the cohort may evaluate to `supported`. This is the
924
+ * gating list; a platform outside it fails closed with
925
+ * `host_cohort_platform_not_audited`. `auditedPlatforms` remains the stricter
926
+ * fact and `auditProvenance` states which one a certificate actually rests
927
+ * on, so a registry-derived graph is never silently reported as a native pass.
928
+ */
929
+ acceptedPlatforms: readonly HostPlatform[];
930
+ auditProvenance: HostAuditProvenance;
512
931
  packages: PackageRow[];
513
932
  capabilities: CapabilityRow[];
514
933
  }
@@ -528,34 +947,41 @@ declare const ALPHA2_HOST_PACKAGES: PackageRow[];
528
947
  */
529
948
  declare const ALPHA2_DSHMARKET_139_HOST_PACKAGES: PackageRow[];
530
949
  /**
531
- * Audited host cohort registry. The rc.2 cohort keeps the exact identities
532
- * audited for 0.3.0/0.3.1 on macOS and Windows. The alpha.2 cohort carries the
533
- * exact package graph extracted from native macOS and Windows DSH
534
- * `0.1.2-alpha.2` / dshmarket `1.38.1` runtimes. The alpha.2+dshmarket-1.39.0
535
- * cohort carries the exact upgraded-Windows graph. The alpha.3 cohort carries
536
- * the graph audited in the 2026-09-01 annex. The rc.1 cohort carries the exact
537
- * runtime plus dshmarket 1.41.0 graph audited natively on macOS, then confirmed
538
- * on Windows: the 2026-09-04 native Windows rc.1 runtime graph (dshmarket
539
- * 1.41.0) was extracted from the runtime lockfile and verified row-for-row
540
- * identical (name, version, registry integrity) to the posix extraction before
541
- * this cohort was widened. Graphs that mix cohorts, lack
542
- * rows, duplicate rows, or use identities outside every registered cohort
543
- * fail closed.
950
+ * Historical audited host cohort registry. Every entry keeps the exact package
951
+ * identities audited natively for a past Guard release (CG-DSH-001 whole-graph
952
+ * contracts). These are historical verification facts only: since 0.5.1 the
953
+ * active support targets are `0.1.5-rc.1` and `0.1.5-rc.2`, so an installed graph from any of
954
+ * these cohorts including previous RCs and alphas is no longer an active
955
+ * support entry and fails closed in `evaluateHostLock`.
544
956
  */
545
957
  declare const LEGACY_HOST_COHORTS: readonly HostCohort[];
958
+ /** Baseline cohort retained for callers that need a default fixture. */
959
+ declare const ACTIVE_HOST_COHORT_ID = "dsh-0.1.5-rc.1";
960
+ declare const ACTIVE_HOST_COHORT_IDS: readonly string[];
546
961
  /** Core-lock/v1 separates optional market identity from the audited DSH graph.
547
- * Legacy rows remain available for historical verification; they are never
548
- * silently re-labelled as a newly accepted core lock.
962
+ * The active support targets are the exact registered rc.1 and rc.2 graphs:
963
+ * historical cohorts stay in `LEGACY_HOST_COHORTS` as verification data but are
964
+ * never silently re-labelled as accepted active locks, and an installed
965
+ * historical graph fails closed under `evaluateHostLock`. The version policy
966
+ * (`>=0.1.5-rc.1`) and the graph lock are separate judgments: a newer host that
967
+ * has not been registered here is "unverified / pending audit", never
968
+ * supported by range alone.
549
969
  */
550
970
  declare const HOST_COHORTS: readonly HostCohort[];
551
971
  /**
552
- * rc.2 audited package identities (first registry cohort). The audited
553
- * cohort is an atomic whole-graph contract (CG-DSH-001): any drifted,
554
- * duplicated, unknown-version, unbound, OR MISSING row fails the whole lock
555
- * closed (`host_lock_missing`); no capability inherits independence from a
556
- * partially present graph.
972
+ * Baseline fixture package identities (DSH 0.1.5-rc.1). The cohort
973
+ * is an atomic whole-graph contract (CG-DSH-001): any drifted, duplicated,
974
+ * unknown-version, unbound, OR MISSING row fails the whole lock closed
975
+ * (`host_lock_missing`); no capability inherits independence from a partially
976
+ * present graph.
557
977
  */
558
978
  declare const EXPECTED_HOST_PACKAGES: PackageRow[];
979
+ /**
980
+ * The `@deepseek-ai/dsh` launcher version of the baseline fixture, read from the
981
+ * cohort rows rather than hardcoded, so a cohort bump cannot leave a stale
982
+ * literal behind in the target-inspection path.
983
+ */
984
+ declare const ACTIVE_HOST_LAUNCHER_VERSION: string | undefined;
559
985
  declare const BASE_HOST_PACKAGES: ReadonlySet<string>;
560
986
  declare const GOAL_HOST_PACKAGES: ReadonlySet<string>;
561
987
  type HostCapabilityId = "agent_loop" | "terminal_posix" | "terminal_windows" | "dsh_cli" | "plugin_inventory" | "web_control" | "jobs" | "filesystem";
@@ -572,14 +998,28 @@ interface HostLockEvaluation {
572
998
  status: HostLockStatus;
573
999
  digest: string;
574
1000
  goalAvailable: boolean;
575
- reasonCode?: "host_lock_migration_required" | "host_lock_installed_graph_drift" | "host_lock_missing" | "host_lock_version_mismatch" | "host_lock_integrity_mismatch" | "host_lock_unknown_package" | "host_lock_duplicate_package" | "host_lock_goal_graph_incomplete" | "host_lock_goal_capability_mismatch" | "host_lock_cohort_mixed_graph" | "host_lock_cohort_unbound_identity" | "host_lock_cohort_platform_not_audited";
1001
+ reasonCode?: "host_lock_migration_required" | "host_lock_installed_graph_drift" | "host_lock_missing" | "host_lock_version_mismatch" | "host_lock_version_below_minimum" | "host_lock_version_unparseable" | "host_lock_integrity_mismatch" | "host_lock_unknown_package" | "host_lock_duplicate_package" | "host_lock_goal_graph_incomplete" | "host_lock_goal_capability_mismatch" | "host_lock_cohort_mixed_graph" | "host_lock_cohort_unbound_identity" | "host_lock_cohort_platform_not_audited";
576
1002
  packages: PackageRow[];
577
1003
  capabilities: Record<HostCapabilityId, HostCapabilityEvaluation>;
578
1004
  platform?: HostPlatform;
579
1005
  profileKind?: HostProfileKind;
580
1006
  liveGoalAvailable?: boolean;
1007
+ /**
1008
+ * The version-policy half of host support, decided separately from the graph.
1009
+ * A host below the minimum is refused here even when its graph matches an
1010
+ * audited cohort, and an in-range version never substitutes for the
1011
+ * exact-graph audit: the two are independent facts, both reported.
1012
+ */
1013
+ hostVersion?: HostVersionDecision;
581
1014
  /** Readback of the audited cohort the supplied graph was evaluated against. */
582
1015
  cohortId?: string;
1016
+ /**
1017
+ * Readback of how that cohort's rows were established. `registry-derived-
1018
+ * pending-native-audit` means the exact published graph was verified but no
1019
+ * native host load has happened yet; a certificate must never present that as
1020
+ * a native pass.
1021
+ */
1022
+ auditProvenance?: HostAuditProvenance;
583
1023
  /** Audited cohort rows absent from the supplied graph (diagnostic). */
584
1024
  missingPackages?: string[];
585
1025
  }
@@ -587,7 +1027,21 @@ interface HostLockContext {
587
1027
  platform?: HostPlatform;
588
1028
  profileKind?: HostProfileKind;
589
1029
  capabilityId?: string;
1030
+ /**
1031
+ * The DSH host version the graph was read from, when the caller read one.
1032
+ * Supplying it turns the version policy into a production decision; omitting
1033
+ * it leaves the version question unanswered rather than assumed supported.
1034
+ */
1035
+ hostVersion?: string;
590
1036
  }
1037
+ /**
1038
+ * The host version a package graph records, for the version-policy decision.
1039
+ *
1040
+ * Every DSH package versions with the host, so the graph's own `dsh` row is the
1041
+ * version the caller is running. A graph without that row leaves the version
1042
+ * unknown, and an unknown version is not treated as supported.
1043
+ */
1044
+ declare function hostVersionFromPackages(rows: readonly PackageRow[]): string | undefined;
591
1045
  type HostCohortSelectionReason = "host_cohort_unknown_package" | "host_cohort_version_mismatch" | "host_cohort_integrity_mismatch" | "host_cohort_mixed_graph" | "host_cohort_incomplete_graph" | "host_cohort_unbound_identity" | "host_cohort_platform_not_audited";
592
1046
  interface HostCohortSelection {
593
1047
  /**
@@ -663,14 +1117,66 @@ declare const DEFAULT_HOST_LOCK: HostLockEvaluation;
663
1117
  declare const CAPTURE_V042_NOTICE = "Context Guard capture boundary: v0.4.2";
664
1118
  declare const PROTOCOL_V3_NOTICE = "Context Guard protocol boundary: v3.0.0";
665
1119
  /**
1120
+ * 0.5.0 first-step boundary: written at the first real root input step (never
1121
+ * at session start), before the constrained root message in the same batch.
1122
+ * It implies the v3 protocol and v0.4.2 capture semantics and marks the cut
1123
+ * where the 0.5 confirmation syntax becomes active; earlier notices keep
1124
+ * their historical meaning for replay.
1125
+ */
1126
+ declare const PROTOCOL_V4_NOTICE = "Context Guard protocol boundary: v4.0.0";
1127
+ /**
666
1128
  * Pure, deterministic re-derivation of the guard projection from the DSH
667
1129
  * native event log. Context Guard never writes custom session events, so every
668
1130
  * piece of state is derived from `command/run`, `user/message`, `tool/call`,
669
- * `tool/result`, `tool/code-dispatch-start`, `tool/code-dispatch`, and
1131
+ * `tool/result`, `tool/ptc-dispatch-start`, `tool/ptc-dispatch`, and
670
1132
  * `compaction/summary`.
671
1133
  */
672
1134
  declare function deriveProjection(sourceEvents: readonly DerivedEnvelope[], config: DeriveConfig, scope: DeriveScope, durableConfirmed: boolean, hostLock?: HostLockEvaluation): DeriveResult;
673
1135
  //#endregion
1136
+ //#region src/domain/diagnostics.d.ts
1137
+ type TaskKind = "inquiry" | "action" | "deliverable" | "constraint" | "unresolved";
1138
+ type CertificationSupport = "supported" | "unsupported" | "needs_target" | "needs_evidence" | "unavailable";
1139
+ type Repairability = "agent_repairable" | "user_input_required" | "unsupported" | "historical_gap" | "none";
1140
+ interface DiagnosisNextAction {
1141
+ kind: "report_only" | "collect_evidence" | "checkpoint" | "clarify_target" | "restore_host" | "none";
1142
+ tool?: string;
1143
+ required_input?: string;
1144
+ resume_condition?: string;
1145
+ }
1146
+ /** The single unified diagnosis shared by checkpoint, recovery, rebind,
1147
+ * evidence/action, and status surfaces (v0.5). It states what certification
1148
+ * can do, never invents targets, evidence IDs, or authority. */
1149
+ interface UnifiedItemDiagnosis {
1150
+ item_id: string;
1151
+ item_revision: number;
1152
+ contract_revision: number;
1153
+ task_kind: TaskKind;
1154
+ certification: CertificationSupport;
1155
+ reason_code: string;
1156
+ repairability: Repairability;
1157
+ missing_fields: string[];
1158
+ missing_facets: Array<"resolution" | "effect" | "state">;
1159
+ next_action: DiagnosisNextAction;
1160
+ /** Stable over unchanged inputs; identical retries collapse onto it. */
1161
+ attempt_fingerprint: string;
1162
+ }
1163
+ /**
1164
+ * The pure repair judge. It decides between: fixable from existing evidence,
1165
+ * missing pre-evidence, missing a user target choice, not supported by any
1166
+ * adapter, an executed-without-evidence historical gap, or nothing to do —
1167
+ * and it NEVER recommends a rebind that cannot change certification.
1168
+ */
1169
+ declare function deriveItemDiagnosis(p: GuardProjection, item: GuardItem): UnifiedItemDiagnosis;
1170
+ /** Legacy compact view, now derived from the single unified diagnosis. */
1171
+ declare function itemDiagnosis(p: GuardProjection, item: GuardItem): {
1172
+ certifiable: boolean;
1173
+ reason_code: string;
1174
+ next_step: string;
1175
+ };
1176
+ declare function evidenceAvailabilityReason(evidence: GuardEvidence): string | undefined;
1177
+ /** Shared display filter; certification remains the full domain check. */
1178
+ declare function relevantEvidence(p: GuardProjection, item: GuardItem, evidence: GuardEvidence): boolean;
1179
+ //#endregion
674
1180
  //#region src/domain/evidence.d.ts
675
1181
  interface ToolCallInput {
676
1182
  callId: string;
@@ -867,6 +1373,12 @@ interface LinearCommitReadback {
867
1373
  * wildcard refspecs, and implicit HEAD/ref destinations fail closed because
868
1374
  * none occur in an accepted exact shape.
869
1375
  */
1376
+ /**
1377
+ * Canonical command templates, derived from the SAME audited argv shapes the
1378
+ * parser accepts above. Guidance surfaces (context_guard_prepare) render these
1379
+ * so a tool description can never advertise a command the executor rejects.
1380
+ */
1381
+ declare const GIT_COMMAND_TEMPLATES: Partial<Record<GitAdapterAction, Record<string, unknown>>>;
870
1382
  declare function parseGitCommandManifest(command: string, surface: CanonicalCommandSurface): GitCommandParseResult;
871
1383
  /** Bind the command's explicit remote/ref identities to the canonical target. */
872
1384
  declare function gitCommandMatchesTarget(manifest: GitCommandManifest, target: GitTargetIdentity): boolean;
@@ -906,6 +1418,18 @@ declare class HostProfileError extends Error {
906
1418
  * callers cannot silently select a nearest instance.
907
1419
  */
908
1420
  declare function packageRowsFromPnpmLock(text: string, names?: readonly string[]): PackageRow[];
1421
+ /**
1422
+ * The production host verdict: the version floor and the exact-graph audit,
1423
+ * combined into the one answer a caller acts on.
1424
+ *
1425
+ * The two facts stay separable — `hostVersion` is always reported on the
1426
+ * evaluation — but a host below the supported floor is refused here even when
1427
+ * its graph matches an audited cohort, because no graph can lift a version
1428
+ * floor. Keeping this combination out of `evaluateHostLock` leaves that
1429
+ * function a pure graph audit, so a graph verdict is never overwritten by a
1430
+ * version verdict inside it.
1431
+ */
1432
+ declare function combineHostPolicy(evaluation: HostLockEvaluation): HostLockEvaluation;
909
1433
  declare function resolveInstalledHostLock(moduleUrl?: string): HostLockEvaluation;
910
1434
  /**
911
1435
  * Resolve only package identities reachable from the active pnpm importer.
@@ -952,6 +1476,75 @@ declare function hostLockContextFromComposedDump(text: string): {
952
1476
  };
953
1477
  declare function verifyComposedHostLockDump(text: string, expected: HostLockEvaluation, roots?: Pick<ActiveProfileHostLock, "runtimeRoot" | "profileRoot">): HostLockEvaluation;
954
1478
  //#endregion
1479
+ //#region src/domain/lifecycle.d.ts
1480
+ /**
1481
+ * Runtime-owned startup lifecycle. It expresses the activation strategy of a
1482
+ * session, never contract or certification state: `armed` means protection is
1483
+ * enabled and waiting for the first real root user input, `active` means that
1484
+ * input has entered a step, and `disabled` means an explicit `off` (or an
1485
+ * opt-in session without `on`). Certification still depends only on durable
1486
+ * root events, the current contract, and the evidence chain.
1487
+ */
1488
+ type LifecyclePhase = "armed" | "active" | "disabled";
1489
+ interface FirstStepInjection {
1490
+ /** Versioned protocol boundary appended before this step's messages. */
1491
+ boundary: string;
1492
+ /** Compact first-step guidance describing the activated protection. */
1493
+ guidance: string;
1494
+ }
1495
+ /** One claimed pre-step message: a validated host `UserMessage`. */
1496
+ interface ClaimedMessage {
1497
+ source?: {
1498
+ kind?: unknown;
1499
+ plugin?: unknown;
1500
+ };
1501
+ content?: unknown;
1502
+ }
1503
+ /**
1504
+ * Pure preview of one claimed pre-step batch. Messages claimed by the loop are
1505
+ * NOT yet persisted as `user/message` events at pre-step time, so this reads
1506
+ * only the validated claim: it never writes contract items, evidence, or
1507
+ * authority. A message activates protection when it carries a root user source
1508
+ * and real content — non-empty text, or any non-text part (image/attachment).
1509
+ * Whitespace-only messages with no other parts are real input but state no
1510
+ * task, so they neither activate nor produce contract items.
1511
+ */
1512
+ declare function claimedBatchHasRealRootInput(messages: readonly unknown[]): boolean;
1513
+ interface FirstStepPreviewInput {
1514
+ activation: "opt-in" | "always";
1515
+ /** Log-derived enablement: an explicit `off` suppresses `always` until `on`. */
1516
+ enabled: boolean;
1517
+ /** The durable log already contains a v4 (or newer) Guard boundary. */
1518
+ boundaryPresent: boolean;
1519
+ /** The session is a delegated/subagent session, never a root conversation. */
1520
+ delegated: boolean;
1521
+ }
1522
+ /**
1523
+ * Pure decision for the first-step activation injection when protection is enabled. The
1524
+ * boundary must precede the first constrained root message inside the SAME
1525
+ * persisted step batch; guidance is compact and never claims a recovery that
1526
+ * did not happen. `opt-in` reaches this path only after its explicit `on` command. Delegated sessions receive neither: their
1527
+ * scope arrives through the parent's delegation prompt (A04).
1528
+ */
1529
+ declare function previewFirstStepInjection(input: FirstStepPreviewInput, claimedRealInput: boolean): FirstStepInjection | undefined;
1530
+ /**
1531
+ * Compact first-step guidance: protection has started, what it protects, and
1532
+ * the working order for stateful actions. It is not a task, asks no question,
1533
+ * and contains no recovery wording.
1534
+ */
1535
+ declare const FIRST_STEP_GUIDANCE = "Context Guard is now protecting this session: requirements from your messages stay open until they are certified with matching durable evidence. Before a stateful action (write, install, commit, push, publish, restart), call context_guard_prepare to see the supported command shape and required resolution/effect/state order; collect evidence with the guarded tools, then close items with context_guard_checkpoint. Ordinary answers and investigations need no certification.";
1536
+ /**
1537
+ * Lifecycle phase derived from durable facts. `enabled` is the log-derived
1538
+ * enablement (`always`, or the explicit `on`/`off` command sequence), and
1539
+ * `realInputSeen` records that a real root user input already entered a step.
1540
+ * Pure over its inputs so status display and tests cannot drift from the
1541
+ * injection decision.
1542
+ */
1543
+ declare function lifecyclePhase(input: {
1544
+ enabled: boolean;
1545
+ realInputSeen: boolean;
1546
+ }): LifecyclePhase;
1547
+ //#endregion
955
1548
  //#region src/domain/manifest.d.ts
956
1549
  /**
957
1550
  * The single source of truth for the certifiable command surface (v0.2).
@@ -1120,22 +1713,130 @@ declare function renderRecoveryPacket(projection: GuardProjection, options?: Rec
1120
1713
  /** Exact 34-row rc.1 runtime/web graph from the 2026-09-03 native macOS audit. */
1121
1714
  declare const RC1_HOST_PACKAGES: PackageRow[];
1122
1715
  //#endregion
1716
+ //#region src/domain/rc015-host.d.ts
1717
+ /**
1718
+ * Exact 33-row DSH 0.1.5-rc.1 core graph.
1719
+ *
1720
+ * Provenance: every row is the npm registry `dist.integrity` of the exact
1721
+ * published tarball for the named version, read from
1722
+ * `https://registry.npmjs.org/<name>/0.1.5-rc.1` (and `4.0.2` for
1723
+ * `@deepseek-ai/cordis`, which is versioned independently of DSH). The single
1724
+ * resolver for this graph is an isolated DSH installation plus the repository
1725
+ * worktree lockfile, both installed from the public registry.
1726
+ *
1727
+ * This is a REGISTRY-DERIVED graph, not a natively audited one: the cohort
1728
+ * carries `auditedPlatforms: []` until a native macOS/Windows host audit runs,
1729
+ * and `auditProvenance: 'registry-derived-pending-native-audit'` is bound into
1730
+ * the host-lock digest so a certificate can never claim a native pass this round
1731
+ * did not produce. (`acceptedPlatforms` is the separate, wider gate: this cohort
1732
+ * accepts evaluation on both platforms while claiming an audit on neither.)
1733
+ * `dshmarket` is deliberately absent: market identity is verified independently
1734
+ * by the action adapter and never participates in the core lock.
1735
+ *
1736
+ * The row-name set is unchanged from the historical 0.1.2-rc.1 cohort's 33
1737
+ * core rows: no package entered or left the audited core graph, so a future
1738
+ * reader must not infer a graph change from the version bump alone. The count
1739
+ * is asserted from this list, never assumed.
1740
+ */
1741
+ declare const RC015_HOST_PACKAGES: PackageRow[];
1742
+ //#endregion
1743
+ //#region src/domain/rc015-rc2-host.d.ts
1744
+ /** Exact npm registry identities for DSH 0.1.5-rc.2 (Cordis 4.0.2).
1745
+ * Native acceptance is recorded separately; these rows are registry-derived.
1746
+ */
1747
+ declare const RC015_RC2_HOST_PACKAGES: PackageRow[];
1748
+ //#endregion
1123
1749
  //#region src/domain/session-events.d.ts
1124
1750
  /**
1125
- * Read a stable snapshot from both legacy DSH Sessions and the rc.1 Session
1126
- * API. rc.1 replaced the public `events` getter with `snapshotEvents()`; the
1127
- * structural adapter keeps older audited cohorts working without widening the
1128
- * accepted event contract.
1751
+ * Read a validated, stable event snapshot from the DSH Session V3 API.
1752
+ *
1753
+ * Session V3 replaced the V2 `events` getter with `snapshotEvents()`. Context
1754
+ * Guard supports only the V3 API: a session object that does not expose that
1755
+ * method is an unsupported host, never a reason to fall back to a legacy
1756
+ * accessor. Failing loud here keeps a V2-shaped object from being projected as
1757
+ * if its events had V3 semantics — the two vocabularies differ (surfaces,
1758
+ * `assistant/chunk` vs embedded streams, `session/end-seed` payload), so a
1759
+ * silent fallback would derive contract state from a log it cannot read.
1760
+ *
1761
+ * Guard is a READER of the durable log, so the envelope check below is the one
1762
+ * part of log validation it owns itself. The host validates a session it
1763
+ * constructs or restores; Guard additionally refuses a snapshot that is not a
1764
+ * sequence of event envelopes, because a projection that silently dropped or
1765
+ * mis-numbered an event would fabricate contract state rather than report a
1766
+ * damaged log.
1767
+ *
1768
+ * The V3 contract also asks a reader to refuse an unrecognized event type that
1769
+ * is not marked `ignorable`. Guard does NOT implement that half, deliberately:
1770
+ * the host's persistence reader already refuses such a log before publishing a
1771
+ * Session, and a whitelist of event types Guard happens to know would
1772
+ * false-refuse a healthy host whose composition registers a required event type
1773
+ * through a third-party plugin. The full rationale is in
1774
+ * `UPSTREAM_API_AUDIT.md`; revisit it there rather than adding a whitelist here.
1129
1775
  */
1776
+ declare const SESSION_API_UNSUPPORTED = "session_api_unsupported";
1777
+ declare const SESSION_EVENT_ENVELOPE_INVALID = "session_event_envelope_invalid";
1778
+ declare class SessionApiError extends Error {
1779
+ readonly code: string;
1780
+ constructor(message: string, code?: string);
1781
+ }
1782
+ /** The V3 session surface Guard reads: one bounded, immutable event snapshot. */
1783
+ interface V3SessionLike {
1784
+ snapshotEvents(fromSeq?: number, toSeqExclusive?: number): readonly unknown[];
1785
+ }
1130
1786
  declare function snapshotSessionEvents(session: unknown): readonly unknown[];
1131
1787
  //#endregion
1132
1788
  //#region src/domain/stop-policy.d.ts
1789
+ /**
1790
+ * What "relevant progress" means, as one value.
1791
+ *
1792
+ * The inputs are the recorded state a caller could not have faked without
1793
+ * changing the work itself: the epoch and contract revision, the open items and
1794
+ * their blockers, the qualified evidence set, the boundary qualifications
1795
+ * available right now, and the Goal's identity and activation. Deliberately
1796
+ * absent: timestamps, event counts, wording, checkpoint bodies, and the Goal
1797
+ * *revision* — editing a Goal's text is not progress, and treating it as such
1798
+ * would let a re-statement reset the stop budget.
1799
+ */
1800
+ /**
1801
+ * How many times the same progress fingerprint must be observed at a turn
1802
+ * boundary before Guard stops the automatic continuation.
1803
+ *
1804
+ * The first sighting is a baseline, not a stalled turn: it is the state a turn
1805
+ * either advanced to or started from, and the host's driver owns continuation
1806
+ * there. The second sighting is the first turn that produced nothing new, which
1807
+ * earns the one diagnosis and correction opportunity. The third is the bounded
1808
+ * stop. The count is a resource bound on repetition, never a way to declare the
1809
+ * task finished.
1810
+ */
1811
+ declare const NO_PROGRESS_TURNS_BEFORE_STOP = 3;
1812
+ /** Marks the durable no-progress record; replay reads the budget from these. */
1813
+ declare const NO_PROGRESS_RECORD_PREFIX = "Context Guard no-progress record: ";
1814
+ /**
1815
+ * The identity of the turn boundary a decision is taken at.
1816
+ *
1817
+ * Guard does not own the host's turn counter, and a retry must be recognisable
1818
+ * as the same boundary rather than as a new one. The last durable event is that
1819
+ * identity: it is derivable from the log alone, it is stable across a reload,
1820
+ * and it only advances when the session actually records something new.
1821
+ */
1822
+ declare function decisionBoundaryKey(projection: GuardProjection): number | undefined;
1823
+ declare function progressFingerprint(projection: GuardProjection): string;
1133
1824
  type CompletionDisposition = "complete" | "user_wait" | "external_wait" | "report";
1134
1825
  declare function isWholeTaskCompletionClaim(text: string): boolean;
1135
1826
  declare function classifyCompletionClaim(text: string): CompletionDisposition;
1136
1827
  interface TurnStoppingDecision {
1137
1828
  action: "continue" | "stop";
1138
1829
  reason?: string;
1830
+ /**
1831
+ * The no-progress attempt this decision asks the caller to record durably.
1832
+ * Recording is the caller's job because it is a durable side effect; deciding
1833
+ * is this function's job and must stay free of them.
1834
+ */
1835
+ noProgressClaim?: {
1836
+ fingerprint: string;
1837
+ boundaryKey: string;
1838
+ attempt: number;
1839
+ };
1139
1840
  }
1140
1841
  interface AssistantOutcomeObservation {
1141
1842
  kind: "completion_claim" | "user_wait_claim" | "external_wait_claim" | "report";
@@ -1152,6 +1853,27 @@ declare function observeAssistantOutcome(text: string): AssistantOutcomeObservat
1152
1853
  */
1153
1854
  declare function decideTurnBoundary(projection: GuardProjection): TurnStoppingDecision;
1154
1855
  declare function decideTurnStopping(projection: GuardProjection, _assistantText: string, _turn: number, _maxAttempts: number): TurnStoppingDecision;
1856
+ /**
1857
+ * Whether the last trusted ROOT instruction asked to pause.
1858
+ *
1859
+ * The source filter is the contract, not a heuristic: a quoted log, a tool
1860
+ * result, a plugin notice or a model message is not a `user/message` with
1861
+ * `source.kind === 'user'`, so none of them can reach this function at all, and
1862
+ * neither can the model's own summary of one. A negated pause ("不要暂停") is not
1863
+ * a pause request, and the check is anchored to a clause head so a pause word
1864
+ * mentioned inside a longer instruction is not a control request.
1865
+ */
1866
+ declare function latestRootInstruction(events: readonly {
1867
+ type: string;
1868
+ seq?: number;
1869
+ data: unknown;
1870
+ }[]): {
1871
+ text: string;
1872
+ seq: number;
1873
+ } | undefined;
1874
+ /** Marks a root control request Guard has already carried to the host. */
1875
+ declare const CONTROL_RECORD_PREFIX = "Context Guard control record: ";
1876
+ declare function isRootPauseRequest(text: string): boolean;
1155
1877
  declare function latestAssistantText(events: readonly {
1156
1878
  type: string;
1157
1879
  data: unknown;
@@ -1160,4 +1882,4 @@ declare function latestAssistantText(events: readonly {
1160
1882
  //#region src/domain/supersession.d.ts
1161
1883
  declare function supersedeItem(items: Map<string, GuardItem>, oldId: string, replacement: GuardItem): boolean;
1162
1884
  //#endregion
1163
- export { packageRowsFromPnpmLock as $, BoundaryDisposition as $n, normalizeClause as $r, GOAL_HOST_PACKAGES as $t, createProofManifest as A, CheckpointResult as An, createProjection as Ar, parsePwshCommand as At, COMMAND_SURFACE_MANIFEST as B, extractMethod as Bn, SUPPORTED_EVIDENCE_ADAPTERS as Br, isDeterministicCheck as Bt, ProofKind as C, AuthorityBlock as Cn, PersistenceAuthorization as Cr, verifiedLinearCommitReadback as Ct, SessionQuery as D, segmentAuthorityBlocks as Dn, TargetValue as Dr, ShellParseStatus as Dt, ProofSurface as E, authorityCaptureCounts as En, TargetTuple as Er, ParsedShell as Et, EvidenceFacetCoverage as F, ClauseSegment as Fn, ActionSpec as Fr, ToolResultInput as Ft, ActiveProfileHostLock as G, BoundaryQualification as Gn, requestedTargetAuthorizesMutation as Gr, ALPHA2_DSHMARKET_139_HOST_PACKAGES as Gt, ManifestIssue as H, isInformationalMessage as Hn, StatefulAction as Hr, CAPTURE_V042_NOTICE as Ht, bindingSatisfies as I, captureClause as In, CERTIFICATE_VERSION as Ir, ToolSubject as It, hostLockContextFromComposedDump as J, GoalBoundaryAccess as Jn, semanticActionFromText as Jr, BASE_HOST_PACKAGES as Jt, HostProfileError as K, BoundaryRequest as Kn, requestedTargetMatchesResolved as Kr, ALPHA2_HOST_PACKAGES as Kt, evidenceCoverage as L, captureItem as Ln, SEMANTIC_ACTIONS as Lr, evidenceFromPersistedToolResult as Lt, proofEvidenceConstraints as M, certifyCheckpoint as Mn, ACTION_MANIFEST as Mr, goalCompletionDenial as Mt, sessionQuery as N, CaptureScope as Nn, ACTION_MANIFEST_VERSION as Nr, hasCurrentCertificate as Nt, bindProofToProjection as O, UserInteractionKind as On, VerificationContract as Or, canonicalArgvFromCommand as Ot, validateProofManifest as P, ClassifiedClause as Pn, ActionManifest as Pr, ToolCallInput as Pt, packageRowsFromActiveGraph as Q, qualifyBoundary as Qn, digestStrings as Qr, ExecutableIdentityBinding as Qt, evidenceMatchesItem as R, classifyClause as Rn, STATEFUL_ACTIONS as Rr, extractTextContent as Rt, PROOF_PROTOCOL_VERSION as S, currentContractDigest as Sn, HostStatus as Sr, revalidateGitPrestate as St, ProofObligation as T, AuthorityKind as Tn, TargetCaptureStatus as Tr, CanonicalCommandSurface as Tt, OperationVerbEntry as U, segmentClauses as Un, actionCompatible as Ur, PROTOCOL_V3_NOTICE as Ut, CommandSurfaceManifest as V, extractOperation as Vn, SemanticAction as Vr, withDurability as Vt, validateManifest as W, BoundaryEffectuation as Wn, isStatefulAction as Wr, deriveProjection as Wt, injectActiveProfileHostLock as X, effectuateBoundary as Xn, validateActionTarget as Xr, EXPECTED_HOST_PACKAGES as Xt, hostLockRowsFromComposedDump as Y, availableBoundaryQualifications as Yn, validateActionManifest as Yr, DEFAULT_HOST_LOCK as Yt, inspectTargetHostGraph as Z, isCurrentAcceptedBoundary as Zn, canonicalizePath as Zr, ExecutableIdentity as Zt, openItems as _, evaluateExternalWaitCapability as _n, GuardItem as _r, commitTreeSnapshotDigest as _t, classifyCompletionClaim as a, HostCohort as an, DerivedEnvelope as ar, GitAdapterAction as at, ALPHA3_HOST_PACKAGES as b, evaluateToolSurfaceCapability as bn, GuardOperation as br, gitCommandMatchesTarget as bt, isWholeTaskCompletionClaim as c, HostLockContext as cn, EvidenceParseStatus as cr, GitCommandParseResult as ct, snapshotSessionEvents as d, HostPlatform as dn, ExternalOperation as dr, GitEffectRunner as dt, sanitizeClauseText as ei, HOST_CAPABILITY_PACKAGE_GROUPS as en, BoundaryQualificationKind as er, readActiveHostGraph as et, RC1_HOST_PACKAGES as f, HostProfileKind as fn, GoalRef as fr, GitPrestateCheck as ft, closingHint as g, bindLiveGoalCapability as gn, GuardIntegrity as gr, commitIndexSnapshotDigest as gt, RecoveryOptions as h, bindExecutableIdentity as hn, GuardEvidence as hr, LinearCommitReadback as ht, TurnStoppingDecision as i, HostCapabilityRequest as in, DeriveScope as ir, GIT_COMMAND_MANIFEST_IDS as it, proofDigest as j, RejectedBinding as jn, PackageRow as jr, parseShellCommand as jt, canonicalProjection as k, classifyUserInteraction as kn, WaitAuthorization as kr, isRunExecutable as kt, latestAssistantText as l, HostLockEvaluation as ln, EvidenceRole as lr, GitCommandRejected as lt, MIN_RECOVERY_CHAR_BUDGET as m, LEGACY_HOST_COHORTS as mn, GuardCheckpoint as mr, GitTargetIdentity as mt, AssistantOutcomeObservation as n, sha256 as ni, HostCapabilityEvaluation as nn, DeriveConfig as nr, resolveInstalledHostLock as nt, decideTurnBoundary as o, HostCohortSelection as on, EvidenceBinding as or, GitCommandAccepted as ot, DEFAULT_RECOVERY_CHAR_BUDGET as p, HostToolSurface as pn, GuardBoundary as pr, GitPrestateEnvelope as pt, TargetHostGraph as q, GoalActivationState as qn, semanticActionFromCommand as qr, AuditedExecutable as qt, CompletionDisposition as r, HostCapabilityId as rn, DeriveResult as rr, verifyComposedHostLockDump as rt, decideTurnStopping as s, HostCohortSelectionReason as sn, EvidenceOutcome as sr, GitCommandManifest as st, supersedeItem as t, sanitizeUrl as ti, HOST_COHORTS as tn, DeferAuthorization as tr, resolveActiveProfileHostLock as tt, observeAssistantOutcome as u, HostLockStatus as un, ExpectedTransition as ur, GitEffectExecution as ut, recoveryDigest as v, evaluateHostCapability as vn, GuardItemKind as vr, createGitPrestateEnvelope as vt, ProofManifest as w, AuthorityBlockKind as wn, TargetCaptureReasonCode as wr, CanonicalArgv as wt, PROOF_KINDS as x, selectHostCohort as xn, GuardProjection as xr, parseGitCommandManifest as xt, renderRecoveryPacket as y, evaluateHostLock as yn, GuardItemStatus as yr, executeRevalidatedGitEffect as yt, isVerifyingCapability as z, extractArtifactPaths as zn, STOP_PROTOCOL_VERSION as zr, extractToolSubject as zt };
1885
+ export { COMMAND_SURFACE_MANIFEST as $, namedActions as $i, bindLiveGoalCapability as $n, BoundaryQualificationKind as $r, parsePwshCommand as $t, openItems as A, PackageRow as Ai, BASE_HOST_PACKAGES as An, RejectedBinding as Ar, GitCommandManifest as At, SessionQuery as B, rebindResponse as Bi, HostCapabilityId as Bn, isInformationalMessage as Br, commitTreeSnapshotDigest as Bt, RC015_RC2_HOST_PACKAGES as C, normalizeClause as Ca, TargetCaptureReasonCode as Ci, deriveProjection as Cn, classifyTaskIntent as Cr, resolveActiveProfileHostLock as Ct, MIN_RECOVERY_CHAR_BUDGET as D, VerificationContract as Di, ALPHA2_DSHMARKET_139_HOST_PACKAGES as Dn, isFrozenV042RebindResponse as Dr, GIT_COMMAND_TEMPLATES as Dt, DEFAULT_RECOVERY_CHAR_BUDGET as E, sha256 as Ea, TargetValue as Ei, ACTIVE_HOST_LAUNCHER_VERSION as En, ParsedConfirmation as Er, GIT_COMMAND_MANIFEST_IDS as Et, PROOF_PROTOCOL_VERSION as F, confirmRebind as Fi, GOAL_HOST_PACKAGES as Fn, captureItem as Fr, GitPrestateCheck as Ft, proofEvidenceConstraints as G, InterpretOptions as Gi, HostLockContext as Gn, GoalActivationState as Gr, revalidateGitPrestate as Gt, canonicalProjection as H, AuthorityDisposition as Hi, HostCohort as Hn, BoundaryEffectuation as Hr, executeRevalidatedGitEffect as Ht, ProofKind as I, proposeRebind as Ii, HOST_CAPABILITY_PACKAGE_GROUPS as In, classifyClause as Ir, GitPrestateEnvelope as It, EvidenceFacetCoverage as J, interpretMessage as Ji, HostPlatform as Jn, effectuateBoundary as Jr, CanonicalCommandSurface as Jt, sessionQuery as K, ScopeInterpretation as Ki, HostLockEvaluation as Kn, GoalBoundaryAccess as Kr, verifiedLinearCommitReadback as Kt, ProofManifest as L, proposeRebindOutcome as Li, HOST_COHORTS as Ln, extractArtifactPaths as Lr, GitTargetIdentity as Lt, renderRecoveryPacket as M, ProposeOutcome as Mi, EXPECTED_HOST_PACKAGES as Mn, CaptureScope as Mr, GitCommandRejected as Mt, ALPHA3_HOST_PACKAGES as N, RebindArgs as Ni, ExecutableIdentity as Nn, ClauseSegment as Nr, GitEffectExecution as Nt, RecoveryOptions as O, WaitAuthorization as Oi, ALPHA2_HOST_PACKAGES as On, parseConfirmationMessage as Or, GitAdapterAction as Ot, PROOF_KINDS as P, RebindProposal as Pi, ExecutableIdentityBinding as Pn, captureClause as Pr, GitEffectRunner as Pt, isVerifyingCapability as Q, maskCodeSpans as Qi, bindExecutableIdentity as Qn, BoundaryDisposition as Qr, isRunExecutable as Qt, ProofObligation as R, proposeRebindV042 as Ri, HostAuditProvenance as Rn, extractMethod as Rr, LinearCommitReadback as Rt, snapshotSessionEvents as S, digestStrings as Sa, PersistenceAuthorization as Si, PROTOCOL_V4_NOTICE as Sn, UserInteractionKind as Sr, readActiveHostGraph as St, RC1_HOST_PACKAGES as T, sanitizeUrl as Ta, TargetTuple as Ti, ACTIVE_HOST_COHORT_IDS as Tn, CONFIRM_LINE_PATTERN as Tr, verifyComposedHostLockDump as Tt, createProofManifest as U, DirectiveClass as Ui, HostCohortSelection as Un, BoundaryQualification as Ur, gitCommandMatchesTarget as Ut, bindProofToProjection as V, replayRebindResult as Vi, HostCapabilityRequest as Vn, segmentClauses as Vr, createGitPrestateEnvelope as Vt, proofDigest as W, Executee as Wi, HostCohortSelectionReason as Wn, BoundaryRequest as Wr, parseGitCommandManifest as Wt, evidenceCoverage as X, isOpenObligation as Xi, HostToolSurface as Xn, qualifyBoundary as Xr, ShellParseStatus as Xt, bindingSatisfies as Y, isExecutableItem as Yi, HostProfileKind as Yn, isCurrentAcceptedBoundary as Yr, ParsedShell as Yt, evidenceMatchesItem as Z, kindOfScope as Zi, LEGACY_HOST_COHORTS as Zn, BindingActionClosure as Zr, canonicalArgvFromCommand as Zt, progressFingerprint as _, semanticActionFromCommand as _a, GuardItemKind as _i, evidenceAvailabilityReason as _n, AuthorityBlockKind as _r, hostLockRowsFromComposedDump as _t, NO_PROGRESS_RECORD_PREFIX as a, ActionSpec as aa, EvidenceBinding as ai, ToolSubject as an, selectHostCohort as ar, FIRST_STEP_GUIDANCE as at, SessionApiError as b, validateActionTarget as ba, GuardProjection as bi, CAPTURE_V042_NOTICE as bn, segmentAuthorityBlocks as br, packageRowsFromActiveGraph as bt, classifyCompletionClaim as c, STATEFUL_ACTIONS as ca, EvidenceRole as ci, extractToolSubject as cn, MIN_SUPPORTED_HOST_VERSION as cr, LifecyclePhase as ct, decisionBoundaryKey as d, SemanticAction as da, GoalRef as di, CertificationSupport as dn, compareHostVersions as dr, previewFirstStepInjection as dt, semanticActionOfScope as ea, DeferAuthorization as ei, parseShellCommand as en, evaluateExternalWaitCapability as er, CommandSurfaceManifest as et, isRootPauseRequest as f, StatefulAction as fa, GuardBoundary as fi, DiagnosisNextAction as fn, evaluateMinimumHostVersion as fr, ActiveProfileHostLock as ft, observeAssistantOutcome as g, requestedTargetMatchesResolved as ga, GuardItem as gi, deriveItemDiagnosis as gn, AuthorityBlock as gr, hostLockContextFromComposedDump as gt, latestRootInstruction as h, requestedTargetAuthorizesMutation as ha, GuardIntegrity as hi, UnifiedItemDiagnosis as hn, currentContractDigest as hr, combineHostPolicy as ht, CompletionDisposition as i, ActionManifest as ia, DerivedEnvelope as ii, ToolResultInput as in, hostVersionFromPackages as ir, ClaimedMessage as it, recoveryDigest as j, BoundedSource as ji, DEFAULT_HOST_LOCK as jn, certifyCheckpoint as jr, GitCommandParseResult as jt, closingHint as k, createProjection as ki, AuditedExecutable as kn, CheckpointResult as kr, GitCommandAccepted as kt, decideTurnBoundary as l, STOP_PROTOCOL_VERSION as la, ExpectedTransition as li, isDeterministicCheck as ln, ParsedHostVersion as lr, claimedBatchHasRealRootInput as lt, latestAssistantText as m, isStatefulAction as ma, GuardEvidence as mi, TaskKind as mn, satisfiesSupportedHostRange as mr, TargetHostGraph as mt, AssistantOutcomeObservation as n, ACTION_MANIFEST as na, DeriveResult as ni, hasCurrentCertificate as nn, evaluateHostLock as nr, OperationVerbEntry as nt, NO_PROGRESS_TURNS_BEFORE_STOP as o, CERTIFICATE_VERSION as oa, EvidenceOutcome as oi, evidenceFromPersistedToolResult as on, HostVersionDecision as or, FirstStepInjection as ot, isWholeTaskCompletionClaim as p, actionCompatible as pa, GuardCheckpoint as pi, Repairability as pn, parseHostVersion as pr, HostProfileError as pt, validateProofManifest as q, interpretClause as qi, HostLockStatus as qn, availableBoundaryQualifications as qr, CanonicalArgv as qt, CONTROL_RECORD_PREFIX as r, ACTION_MANIFEST_VERSION as ra, DeriveScope as ri, ToolCallInput as rn, evaluateToolSurfaceCapability as rr, validateManifest as rt, TurnStoppingDecision as s, SEMANTIC_ACTIONS as sa, EvidenceParseStatus as si, extractTextContent as sn, HostVersionStatus as sr, FirstStepPreviewInput as st, supersedeItem as t, statefulActionsOfScope as ta, DeriveConfig as ti, goalCompletionDenial as tn, evaluateHostCapability as tr, ManifestIssue as tt, decideTurnStopping as u, SUPPORTED_EVIDENCE_ADAPTERS as ua, ExternalOperation as ui, withDurability as un, SUPPORTED_HOST_RANGE as ur, lifecyclePhase as ut, SESSION_API_UNSUPPORTED as v, semanticActionFromText as va, GuardItemStatus as vi, itemDiagnosis as vn, AuthorityKind as vr, injectActiveProfileHostLock as vt, RC015_HOST_PACKAGES as w, sanitizeClauseText as wa, TargetCaptureStatus as wi, ACTIVE_HOST_COHORT_ID as wn, classifyUserInteraction as wr, resolveInstalledHostLock as wt, V3SessionLike as x, canonicalizePath as xa, HostStatus as xi, PROTOCOL_V3_NOTICE as xn, TaskIntent as xr, packageRowsFromPnpmLock as xt, SESSION_EVENT_ENVELOPE_INVALID as y, validateActionManifest as ya, GuardOperation as yi, relevantEvidence as yn, authorityCaptureCounts as yr, inspectTargetHostGraph as yt, ProofSurface as z, rebindAttemptKey as zi, HostCapabilityEvaluation as zn, extractOperation as zr, commitIndexSnapshotDigest as zt };