dsh-completion-guard 0.6.2 → 0.7.0

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.
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
- import { $ as extractToolSubject, $n as proposeRebindV042, $r as requestedTargetMatchesResolved, $t as proofDigest, A as lifecyclePhase, An as NO_PROGRESS_RECORD_PREFIX, Ar as isOpenObligation, At as compareHostVersions, B as RELEASE_RESERVATION_PREFIX, Bn as observeAssistantOutcome, Br as BOUNDED_ARTIFACT_TYPES, Bt as certifyCheckpoint, C as gitCommandMatchesTarget, Cn as recoveryDigest, Cr as extractMethod, Ct as evaluateToolSurfaceCapability, D as FIRST_STEP_GUIDANCE, Dn as evidenceMatchesItem, Dr as interpretClause, Dt as MIN_SUPPORTED_HOST_VERSION, E as verifiedLinearCommitReadback, En as evidenceCoverage, Er as segmentClauses, Et as LATEST_SUPPORTED_HOST_VERSION, F as PROTOCOL_V4_NOTICE, Fn as decisionBoundaryKey, Fr as statefulActionsOfScope, Ft as RC015_HOST_PACKAGES, G as readbackSettlesContract, Gn as effectuateBoundary, Gr as STOP_PROTOCOL_VERSION, Gt as PROOF_PROTOCOL_VERSION, H as contractById, Hn as goalCompletionDenial, Hr as CERTIFICATE_VERSION_V2, Ht as PROOF_KINDS, I as PROTOCOL_V5_NOTICE, In as isRootPauseRequest, Ir as canonicalRegistryBase, It as RC1_HOST_PACKAGES, J as releasePreEffectDecision, Jn as currentContractDigest, Jr as actionCompatible, Jt as bindProofV2ToProjection, K as releaseContractFor, Kn as isCurrentAcceptedBoundary, Kr as STOP_PROTOCOL_VERSION_V2, Kt as PROOF_PROTOCOL_VERSION_V2, L as deriveProjection, Ln as isWholeTaskCompletionClaim, Lr as npmEscapedPackageName, Lt as ALPHA3_HOST_PACKAGES, M as CAPTURE_V042_NOTICE, Mn as classifyCompletionClaim, Mr as maskCodeSpans, Mt as parseHostVersion, N as DEFAULT_DELEGATION_TOOL_NAMES, Nn as decideTurnBoundary, Nr as namedActions, Nt as satisfiesSupportedHostRange, O as claimedBatchHasRealRootInput, On as isVerifyingCapability, Or as interpretMessage, Ot as SUPPORTED_HOST_RANGE, P as PROTOCOL_V3_NOTICE, Pn as decideTurnStopping, Pr as semanticActionOfScope, Pt as RC015_RC2_HOST_PACKAGES, Q as extractTextContent, Qn as proposeRebindOutcome, Qr as requestedTargetAuthorizesMutation, Qt as proofCapabilityReport, R as RELEASE_OPERATIONS, Rn as latestAssistantText, Rr as ACTION_MANIFEST, Rt as authorityCaptureCounts, S as executeRevalidatedGitEffect, Sn as openItems, Sr as extractArtifactPaths, St as evaluateHostLock, T as revalidateGitPrestate, Tn as bindingSatisfies, Tr as isInformationalMessage, Tt as selectHostCohort, U as inFlightReservation, Un as hasCurrentCertificate, Ur as SEMANTIC_ACTIONS, Ut as PROOF_KINDS_V2, V as RELEASE_SETTLEMENT_PREFIX, Vn as progressFingerprint, Vr as CERTIFICATE_VERSION, Vt as PROOF_CAPABILITY_MATRIX, W as normalizeReleaseContract, Wn as availableBoundaryQualifications, Wr as STATEFUL_ACTIONS, Wt as PROOF_MANIFEST_DOMAIN_V2, X as supersedeItem, Xn as confirmRebind, Xr as isStatefulAction, Xt as createProofManifest, Y as reservationFor, Yn as createProjection, Yr as boundedArtifactChoiceMatches, Yt as canonicalProjection, Z as evidenceFromPersistedToolResult, Zn as proposeRebind, Zr as requestedIdentityKey, Zt as createProofManifestV2, _ as GIT_COMMAND_MANIFEST_IDS, _n as DEFAULT_RECOVERY_CHAR_BUDGET, _r as removalIsComplete, _t as LEGACY_HOST_COHORTS, a as injectActiveProfileHostLock, ai as validateManifest, an as requiredSubjectsOf, ar as parseConfirmationMessage, at as parseShellCommand, b as commitTreeSnapshotDigest, bn as cleanupConditionFor, br as captureItem, bt as evaluateExternalWaitCapability, c as packageRowsFromPnpmLock, ci as canonicalizePath, cn as sessionQueryV2, cr as evidenceAvailabilityReason, ct as ACTIVE_HOST_LAUNCHER_VERSION, d as resolveInstalledHostLock, di as sanitizeClauseText, dn as certifiableOpenItems, dr as DEPENDENCY_FREE_ONLY_CONDITION, dt as BASE_HOST_PACKAGES, ei as semanticActionFromCommand, en as proofDigestV2, er as rebindAttemptKey, et as isDeterministicCheck, f as verifyComposedHostLockDump, fi as sanitizeUrl, fn as certificateClosure, fr as actionHasCertificationPath, ft as DEFAULT_HOST_LOCK, g as snapshotSessionEvents, gn as CLEANUP_CONDITION_RULE_SHORT, gr as partialFailureOf, gt as HOST_COHORTS, h as SessionApiError, hn as CLEANUP_CONDITION_RULE_COMPACT, hr as capabilityFactOf, ht as HOST_CAPABILITY_PACKAGE_GROUPS, i as hostLockRowsFromComposedDump, ii as COMMAND_SURFACE_MANIFEST, in as proofV2Rejection, ir as isFrozenV042RebindResponse, it as parsePwshCommand, j as previewFirstStepInjection, jn as NO_PROGRESS_TURNS_BEFORE_STOP, jr as kindOfScope, jt as evaluateMinimumHostVersion, k as firstStepGuidance, kn as CONTROL_RECORD_PREFIX, kr as isExecutableItem, kt as SUPPORTED_HOST_VERSIONS, l as readActiveHostGraph, li as digestStrings, ln as validateProofManifest, lr as itemDiagnosis, lt as ALPHA2_DSHMARKET_139_HOST_PACKAGES, m as SESSION_EVENT_ENVELOPE_INVALID, mn as CLEANUP_CONDITION_RULE, mr as capabilityConsequence, mt as GOAL_HOST_PACKAGES, n as combineHostPolicy, ni as validateActionManifest, nn as proofHostSurfacesOf, nr as replayRebindResult, nt as canonicalArgvFromCommand, o as inspectTargetHostGraph, oi as classifyTaskIntent, on as scopeCoverageDigest, or as capabilityRemedyPhrase, ot as ACTIVE_HOST_COHORT_ID, p as SESSION_API_UNSUPPORTED, pi as sha256, pn as unitDescendantIds, pr as admissibleForRemoval, pt as EXPECTED_HOST_PACKAGES, q as releaseCoverage, qn as qualifyBoundary, qr as SUPPORTED_EVIDENCE_ADAPTERS, qt as bindProofToProjection, r as hostLockContextFromComposedDump, ri as validateActionTarget, rn as proofOperationMatches, rr as CONFIRM_LINE_PATTERN, rt as isRunExecutable, s as packageRowsFromActiveGraph, si as classifyUserInteraction, sn as sessionQuery, sr as deriveItemDiagnosis, st as ACTIVE_HOST_COHORT_IDS, t as HostProfileError, ti as semanticActionFromText, tn as proofEvidenceConstraints, tr as rebindResponse, tt as withDurability, u as resolveActiveProfileHostLock, ui as normalizeClause, un as validateProofManifestV2, ur as relevantEvidence, ut as ALPHA2_HOST_PACKAGES, v as GIT_COMMAND_TEMPLATES, vn as MIN_RECOVERY_CHAR_BUDGET, vr as removalIsPartiallyKnown, vt as bindExecutableIdentity, w as parseGitCommandManifest, wn as renderRecoveryPacket, wr as extractOperation, wt as hostVersionFromPackages, x as createGitPrestateEnvelope, xn as closingHint, xr as classifyClause, xt as evaluateHostCapability, y as commitIndexSnapshotDigest, yn as carriesCleanupCondition, yr as captureClause, yt as bindLiveGoalCapability, z as RELEASE_OPERATION_SURFACES, zn as latestRootInstruction, zr as ACTION_MANIFEST_VERSION, zt as segmentAuthorityBlocks } from "./domain-BtR3J5aL.js";
1
+ import { $ as currentV6Feedback, $i as requestedIdentityKey, $n as decideTurnStopping, $r as npmEscapedPackageName, $t as RC015_RC2_HOST_PACKAGES, A as firstStepGuidanceV6, Ai as opensWithDirective, An as CLEANUP_CONDITION_RULE, Ar as capabilityRemedyPhrase, At as BASE_HOST_PACKAGES, B as SessionApiError, Bi as ACTION_MANIFEST, Bn as renderRecoveryPacket, Br as partialFailureOf, Bt as evaluateHostCapability, C as gitCommandMatchesTarget, Ci as itemHoldsExecutionAuthority, Cn as proofV2Rejection, Cr as proposeRebindV042, Ct as parsePwshCommand, D as FIRST_STEP_GUIDANCE, Di as maskQuotedSpans, Dn as sessionQueryV2, Dr as CONFIRM_LINE_PATTERN, Dt as ACTIVE_HOST_LAUNCHER_VERSION, E as verifiedLinearCommitReadback, Ei as maskCodeSpans, En as sessionQuery, Er as replayRebindResult, Et as ACTIVE_HOST_COHORT_IDS, F as HOST_WORKDIR_PREFIX, Fi as restatedContentOf, Fn as carriesCleanupCondition, Fr as DEPENDENCY_FREE_ONLY_CONDITION, Ft as HOST_COHORTS, G as PROTOCOL_V3_NOTICE, Gi as SEMANTIC_ACTIONS, Gn as CONTROL_RECORD_PREFIX, Gr as classifyClause, Gt as LATEST_SUPPORTED_HOST_VERSION, H as projectCoreV2, Hi as BOUNDED_ARTIFACT_TYPES, Hn as evidenceCoverage, Hr as removalIsPartiallyKnown, Ht as evaluateToolSurfaceCapability, I as captureHostWorkdir, Ii as semanticActionOfScope, In as cleanupConditionFor, Ir as actionHasCertificationPath, It as LEGACY_HOST_COHORTS, J as PROTOCOL_V6_NOTICE, Ji as STOP_PROTOCOL_VERSION_V2, Jn as assessmentAction, Jr as extractMethod, Jt as SUPPORTED_HOST_VERSIONS, K as PROTOCOL_V4_NOTICE, Ki as STATEFUL_ACTIONS, Kn as NO_PROGRESS_RECORD_PREFIX, Kr as environmentDefaultRepositoryTarget, Kt as MIN_SUPPORTED_HOST_VERSION, L as sourcedNamedTestRoot, Li as splitTextFragments, Ln as closingHint, Lr as admissibleForRemoval, Lt as bindExecutableIdentity, M as previewFirstStepInjection, Mi as qualificationOfClause, Mn as CLEANUP_CONDITION_RULE_SHORT, Mr as evidenceAvailabilityReason, Mt as EXPECTED_HOST_PACKAGES, N as projectSessionCoreV2, Ni as questionHeadsClause, Nn as DEFAULT_RECOVERY_CHAR_BUDGET, Nr as itemDiagnosis, Nt as GOAL_HOST_PACKAGES, O as claimedBatchHasRealRootInput, Oi as namedActions, On as validateProofManifest, Or as isFrozenV042RebindResponse, Ot as ALPHA2_DSHMARKET_139_HOST_PACKAGES, P as sessionCoreSnapshot, Pi as reportingHeadGoverns, Pn as MIN_RECOVERY_CHAR_BUDGET, Pr as relevantEvidence, Pt as HOST_CAPABILITY_PACKAGE_GROUPS, Q as rootLocatorFlavor, Qi as isStatefulAction, Qn as decideTurnBoundary, Qr as canonicalRegistryBase, Qt as satisfiesSupportedHostRange, R as SESSION_API_UNSUPPORTED, Ri as statefulActionsOfScope, Rn as openItems, Rr as capabilityConsequence, Rt as bindLiveGoalCapability, S as executeRevalidatedGitEffect, Si as isRestatement, Sn as proofOperationMatches, Sr as proposeRebindOutcome, St as isRunExecutable, T as revalidateGitPrestate, Ti as legacyQuestionReadingIsInformational, Tn as scopeCoverageDigest, Tr as rebindResponse, Tt as ACTIVE_HOST_COHORT_ID, U as CAPTURE_V042_NOTICE, Ui as CERTIFICATE_VERSION, Un as evidenceMatchesItem, Ur as captureClause, Ut as hostVersionFromPackages, V as snapshotSessionEvents, Vi as ACTION_MANIFEST_VERSION, Vn as bindingSatisfies, Vr as removalIsComplete, Vt as evaluateHostLock, W as DEFAULT_DELEGATION_TOOL_NAMES, Wi as CERTIFICATE_VERSION_V2, Wn as isVerifyingCapability, Wr as captureItem, Wt as selectHostCohort, X as deriveProjection, Xi as actionCompatible, Xn as classifyCompletionClaim, Xr as isInformationalMessage, Xt as evaluateMinimumHostVersion, Y as applyUpgradeEligibility, Yi as SUPPORTED_EVIDENCE_ADAPTERS, Yn as assessmentOutcomePredicate, Yr as extractOperation, Yt as compareHostVersions, Z as legacyRecordsNeedingReview, Zi as boundedArtifactChoiceMatches, Zn as currentActionBases, Zr as segmentClauses, Zt as parseHostVersion, _ as GIT_COMMAND_MANIFEST_IDS, _i as isExecutableItem, _n as proofCapabilityReport, _r as qualifyBoundary, _t as extractToolSubject, a as auditedForegroundRenderers, aa as validateActionTarget, ai as clarifiedSpanOf, an as certifyCheckpoint, ar as observeAssistantOutcome, at as inFlightReservation, b as commitTreeSnapshotDigest, bi as isOpenObligation, bn as proofEvidenceConstraints, br as confirmRebind, bt as withDurability, c as hostLockRowsFromComposedDump, ca as canonicalizePath, ci as clauseIsProtected, cn as PROOF_KINDS_V2, cr as v6TestPredicate, ct as normalizeSettlement, d as packageRowsFromActiveGraph, da as sanitizeClauseText, di as hasOrderedCoordination, dn as PROOF_PROTOCOL_VERSION_V2, dr as certifiableOpenItems, dt as releaseCoverage, ea as requestedTargetAuthorizesMutation, ei as classifyTaskIntent, en as RC015_HOST_PACKAGES, er as decisionBoundaryKey, et as sourceItemForCoreRequirement, f as packageRowsFromPnpmLock, fa as sanitizeUrl, fi as hasQuestionScope, fn as bindProofToProjection, fr as certificateClosure, ft as releasePreEffectDecision, g as verifyComposedHostLockDump, gi as introducesActionClause, gn as createProofManifestV2, gr as isCurrentAcceptedBoundary, gt as extractTextContent, h as resolveInstalledHostLock, hi as interpretMessage, hn as createProofManifest, hr as effectuateBoundary, ht as evidenceFromPersistedToolResult, i as auditedDefaultWorkdirProvider, ia as validateActionManifest, ii as actionVerbMatches, in as segmentAuthorityBlocks, ir as latestRootInstruction, it as contractById, j as lifecyclePhase, ji as presentExplanationHead, jn as CLEANUP_CONDITION_RULE_COMPACT, jr as deriveItemDiagnosis, jt as DEFAULT_HOST_LOCK, k as firstStepGuidance, ki as opensConditionLead, kn as validateProofManifestV2, kr as parseConfirmationMessage, kt as ALPHA2_HOST_PACKAGES, l as injectActiveProfileHostLock, la as digestStrings, li as explanationHasActionResidue, ln as PROOF_MANIFEST_DOMAIN_V2, lr as goalCompletionDenial, lt as readbackSettlesContract, m as resolveActiveProfileHostLock, mi as interpretClause, mn as canonicalProjection, mr as availableBoundaryQualifications, mt as supersedeItem, n as activeRendererModule, na as semanticActionFromCommand, ni as GRANTED_QUALIFICATION, nn as ALPHA3_HOST_PACKAGES, nr as isWholeTaskCompletionClaim, nt as RELEASE_OPERATIONS, o as combineHostPolicy, oa as COMMAND_SURFACE_MANIFEST, oi as clauseAsksOwnQuestion, on as PROOF_CAPABILITY_MATRIX, or as progressFingerprint, ot as normalizeReleaseContract, p as readActiveHostGraph, pa as sha256, pi as hasWorkPredicate, pn as bindProofV2ToProjection, pr as unitDescendantIds, pt as reservationFor, q as PROTOCOL_V5_NOTICE, qi as STOP_PROTOCOL_VERSION, qn as NO_PROGRESS_TURNS_BEFORE_STOP, qr as extractArtifactPaths, qt as SUPPORTED_HOST_RANGE, r as auditedDefaultWorkdirHost, ra as semanticActionFromText, ri as LEGACY_QUALIFICATION, rn as authorityCaptureCounts, rr as latestAssistantText, rt as RELEASE_OPERATION_SURFACES, s as hostLockContextFromComposedDump, sa as validateManifest, si as clauseIsGoverned, sn as PROOF_KINDS, sr as testOutcomePredicate, st as normalizeReservation, t as HostProfileError, ta as requestedTargetMatchesResolved, ti as classifyUserInteraction, tn as RC1_HOST_PACKAGES, tr as isRootPauseRequest, tt as OUTCOME_STRENGTH, u as inspectTargetHostGraph, ua as normalizeClause, ui as governedClauseRestrictsExecution, un as PROOF_PROTOCOL_VERSION, ur as hasCurrentCertificate, ut as releaseContractFor, v as GIT_COMMAND_TEMPLATES, vi as isExplanationScope, vn as proofDigest, vr as currentContractDigest, vt as isDeterministicCheck, w as parseGitCommandManifest, wi as kindOfScope, wn as requiredSubjectsOf, wr as rebindAttemptKey, wt as parseShellCommand, x as createGitPrestateEnvelope, xi as isQuestionScopeNeedingReview, xn as proofHostSurfacesOf, xr as proposeRebind, xt as canonicalArgvFromCommand, y as commitIndexSnapshotDigest, yi as isInformationalFragment, yn as proofDigestV2, yr as createProjection, yt as persistedToolResultStatus, z as SESSION_EVENT_ENVELOPE_INVALID, zi as verbIsNegated, zn as recoveryDigest, zr as capabilityFactOf, zt as evaluateExternalWaitCapability } from "./domain-B3EuAllT.js";
2
2
  import { defineTool } from "@deepseek-ai/dsh-tools";
3
3
  import { createHash } from "node:crypto";
4
- import { basename, delimiter, dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { basename, delimiter, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
5
+ import { homedir, tmpdir } from "node:os";
5
6
  import { boundContextSummary, createToolResultMessage, createUserMessage } from "@deepseek-ai/dsh-llm";
7
+ import { closeSync, constants, existsSync, fchmodSync, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, unlinkSync, writeSync } from "node:fs";
8
+ import { promisify } from "node:util";
6
9
  import { execFile } from "node:child_process";
7
- import { constants, existsSync, readFileSync } from "node:fs";
8
10
  import { access, readFile, realpath } from "node:fs/promises";
9
- import { tmpdir } from "node:os";
10
11
  import { fileURLToPath } from "node:url";
11
- import { promisify } from "node:util";
12
12
  import { gunzip } from "node:zlib";
13
- import { SESSION_FORMAT_VERSION } from "@deepseek-ai/dsh-session";
13
+ import { SESSION_FORMAT_VERSION, Session, SessionId } from "@deepseek-ai/dsh-session";
14
14
 
15
15
  //#region src/tools/rebind.ts
16
16
  function createRebindTool(getProjection, prepare) {
@@ -86,6 +86,7 @@ function checkpointPage(p, query, full) {
86
86
  revision: p.contractRevision,
87
87
  evidence: [...p.evidence.values()],
88
88
  items: [...p.items.values()],
89
+ ...full.current_feedback === true ? { current_core: p.coreV2 } : {},
89
90
  item_ids,
90
91
  evidence_ids,
91
92
  evidence_scope,
@@ -167,12 +168,23 @@ function checkpointPage(p, query, full) {
167
168
  available_evidence: [],
168
169
  available_qualifications: []
169
170
  };
171
+ if (full.current_feedback === true) {
172
+ output.reason_code = full.reason_code;
173
+ output.feedback_source = "confirmed_core_v2";
174
+ output.current_actions = (full.current_actions ?? []).slice(0, 8);
175
+ output.current_action_total = (full.current_actions ?? []).length;
176
+ output.certificate_status = "not_requested";
177
+ }
170
178
  if (full.certificate) output.certificate = full.certificate;
171
179
  if (full.proof_state) output.proof_state = full.proof_state;
172
180
  const pagination = {
173
181
  snapshot: identity,
174
182
  scope: evidence_scope,
175
- counts: {
183
+ counts: full.current_feedback === true ? {
184
+ pending: full.open_items.length,
185
+ passed: Object.values(p.coreV2?.predicates ?? {}).filter((value) => value === "satisfied").length,
186
+ superseded: 0
187
+ } : {
176
188
  pending: [...p.items.values()].filter((i) => i.status === "pending").length,
177
189
  passed: [...p.items.values()].filter((i) => i.status === "passed").length,
178
190
  superseded: [...p.items.values()].filter((i) => i.status === "superseded").length
@@ -185,6 +197,10 @@ function checkpointPage(p, query, full) {
185
197
  id: String(row.id ?? row.item_id).slice(0, 128),
186
198
  reason_code: row.reason_code,
187
199
  certifiable: row.certifiable,
200
+ source_item_id: row.source_item_id,
201
+ revision: row.revision,
202
+ kind: row.kind,
203
+ semantic_action: row.semantic_action,
188
204
  next_step: typeof row.next_step === "string" ? row.next_step.slice(0, 240) : void 0,
189
205
  adapter_disposition: row.adapter_disposition,
190
206
  ...row.binding_template !== void 0 ? { binding_template: row.binding_template } : {},
@@ -352,7 +368,7 @@ function openItemForTool(projection, item) {
352
368
  function createCheckpointTool(getProjection, onRejected, prepare = async () => true) {
353
369
  return defineTool({
354
370
  name: "context_guard_checkpoint",
355
- description: "Request a completion certificate from existing durable evidence.",
371
+ description: "Read current ordinary closure from confirmed observations; request a certificate only for an explicitly adopted proof, Goal, or release contract.",
356
372
  parameters: {
357
373
  item_ids: {
358
374
  type: "array",
@@ -508,10 +524,27 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
508
524
  type: "string",
509
525
  enum: [
510
526
  "certified",
527
+ "observed",
511
528
  "incomplete",
512
529
  "unknown"
513
530
  ]
514
531
  },
532
+ feedback_source: {
533
+ type: "string",
534
+ enum: ["confirmed_core_v2"]
535
+ },
536
+ current_actions: {
537
+ type: "array",
538
+ items: {
539
+ type: "object",
540
+ additionalProperties: true
541
+ }
542
+ },
543
+ current_action_total: { type: "integer" },
544
+ certificate_status: {
545
+ type: "string",
546
+ enum: ["not_requested"]
547
+ },
515
548
  contract_revision: { type: "integer" },
516
549
  active_constraints: {
517
550
  type: "array",
@@ -638,6 +671,22 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
638
671
  certification_digest: { type: "string" },
639
672
  unit_id: { type: "string" },
640
673
  unit_closure_digest: { type: "string" },
674
+ root_locator_identity: { type: "string" },
675
+ native_observations: {
676
+ type: "object",
677
+ additionalProperties: false,
678
+ properties: {
679
+ schema: {
680
+ type: "string",
681
+ required: true
682
+ },
683
+ digests: {
684
+ type: "array",
685
+ required: true,
686
+ items: { type: "string" }
687
+ }
688
+ }
689
+ },
641
690
  goal_ref: { oneOf: [{
642
691
  type: "object",
643
692
  additionalProperties: false,
@@ -670,6 +719,46 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
670
719
  rejected_bindings: []
671
720
  };
672
721
  }
722
+ const currentFeedback = args.proof === void 0 ? currentV6Feedback(projection) : void 0;
723
+ if (currentFeedback) {
724
+ const openRows = currentFeedback.openIds.map((id) => {
725
+ const sourced = sourceItemForCoreRequirement(projection, id);
726
+ return {
727
+ id,
728
+ reason_code: currentFeedback.predicates[id],
729
+ ...sourced ? {
730
+ source_item_id: sourced.item.id,
731
+ revision: sourced.item.revision,
732
+ kind: sourced.item.kind,
733
+ text: sourced.item.normalizedText
734
+ } : {},
735
+ ...sourced?.origin ? {
736
+ source_start: sourced.origin.sourceStart,
737
+ source_end: sourced.origin.sourceEnd,
738
+ semantic_action: sourced.origin.action,
739
+ target: sourced.origin.target
740
+ } : sourced?.item.semanticAction ? { semantic_action: sourced.item.semanticAction } : {},
741
+ next_step: "Answer this sourced requirement using the current Host observation or final delivery; ordinary Guard bindings are not required."
742
+ };
743
+ });
744
+ const constraints = Object.entries(currentFeedback.predicates).filter(([, state]) => state === "constraint_active" || state === "constraint_unresolved" || state === "constraint_violated").map(([id, state]) => ({
745
+ id,
746
+ reason_code: state
747
+ }));
748
+ return checkpointPage(projection, args, {
749
+ status: currentFeedback.status,
750
+ reason_code: currentFeedback.reasonCode,
751
+ current_feedback: true,
752
+ contract_revision: projection.contractRevision,
753
+ blocking_total: openRows.length,
754
+ open_items: openRows,
755
+ active_constraints: constraints,
756
+ available_evidence: [],
757
+ available_qualifications: [],
758
+ rejected_bindings: [],
759
+ current_actions: currentFeedback.currentActions
760
+ });
761
+ }
673
762
  const bindings = args.bindings.map((binding) => ({
674
763
  itemId: binding.item_id,
675
764
  evidenceIds: binding.evidence_ids,
@@ -796,6 +885,8 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
796
885
  open_digest: result.checkpoint.openDigest,
797
886
  evidence_sha256: result.checkpoint.evidenceSha256,
798
887
  binding_digest: result.checkpoint.bindingDigest,
888
+ ...result.checkpoint.nativeObservations ? { native_observations: result.checkpoint.nativeObservations } : {},
889
+ ...result.checkpoint.rootLocatorIdentity ? { root_locator_identity: result.checkpoint.rootLocatorIdentity } : {},
799
890
  certification_digest: result.checkpoint.certificationDigest,
800
891
  ...result.checkpoint.unitId !== void 0 ? {
801
892
  unit_id: result.checkpoint.unitId,
@@ -1124,8 +1215,103 @@ function actionPreparation(action) {
1124
1215
  }
1125
1216
  }
1126
1217
 
1218
+ //#endregion
1219
+ //#region src/domain/compatibility.ts
1220
+ /** The identity field a caller must supply for this action, when it has one. */
1221
+ function requiredIdentityFieldOf(action) {
1222
+ return requestedIdentityKey(action);
1223
+ }
1224
+ /**
1225
+ * The single compatibility judgement. `input.resolvedTarget` is compared with
1226
+ * the item's own requested target using the caller-supplied relation, so this
1227
+ * module never re-implements target identity: the caller passes the same
1228
+ * predicate it would use when authorizing.
1229
+ */
1230
+ function evaluateCompatibility(input, targetMatches) {
1231
+ const identityField = requiredIdentityFieldOf(input.action);
1232
+ const base = {
1233
+ assumedAction: input.action,
1234
+ ...identityField !== void 0 ? { requiredIdentityField: identityField } : {},
1235
+ itemAction: input.itemAction,
1236
+ certifiable: input.adapterSupported === true || !isStatefulAction(input.action)
1237
+ };
1238
+ const incompatible = (reasonCode) => ({
1239
+ ...base,
1240
+ status: "incompatible",
1241
+ reasonCodes: [reasonCode],
1242
+ semanticsCompatible: reasonCode !== "action_not_compatible_with_item" && reasonCode !== "rebind_does_not_authorize_action",
1243
+ targetCompatible: reasonCode !== "requested_resolved_target_mismatch"
1244
+ });
1245
+ const blocked = (reasonCode) => ({
1246
+ ...base,
1247
+ status: "blocked",
1248
+ reasonCodes: [reasonCode],
1249
+ semanticsCompatible: true,
1250
+ targetCompatible: true
1251
+ });
1252
+ if (input.itemRevision !== void 0 && input.currentRevision !== void 0 && input.itemRevision !== input.currentRevision) return {
1253
+ ...blocked("item_revision_mismatch"),
1254
+ certifiable: false
1255
+ };
1256
+ if (input.action !== input.itemAction && !actionCompatible(input.itemAction, input.action)) return incompatible("action_not_compatible_with_item");
1257
+ if (input.reboundFrom && input.originalAuthority?.semanticAction === input.itemAction && input.originalAuthority.semanticAction !== input.action) return incompatible("rebind_does_not_authorize_action");
1258
+ const itemSelectedTarget = input.targetCaptureStatus === "resolved" && input.targetSourceKind !== "environment_default";
1259
+ if (input.action === input.itemAction && input.resolvedTarget !== void 0 && itemSelectedTarget && !input.boundedSelectionAuthorized && !targetMatches(input.requestedTarget, input.resolvedTarget)) return {
1260
+ ...incompatible("requested_resolved_target_mismatch"),
1261
+ semanticsCompatible: true,
1262
+ targetCompatible: false
1263
+ };
1264
+ if (input.enabled === false) return blocked("guard_disabled");
1265
+ if (input.integrity !== void 0 && input.integrity !== "valid") return blocked("guard_integrity_unavailable");
1266
+ if (input.hostStatus !== void 0 && input.hostStatus !== "supported") return blocked("host_lock_unavailable");
1267
+ if (input.itemKind === "prohibition") return blocked("prohibition_active");
1268
+ if (input.itemStatus !== void 0 && input.itemStatus !== "pending") return blocked("item_not_pending");
1269
+ if (input.itemKind !== void 0 && input.itemKind !== "requirement") return blocked("item_not_authorizing");
1270
+ if (input.authority !== void 0 && input.authority !== "root_instruction" && input.authority !== "root_adoption") return blocked("root_authority_unavailable");
1271
+ if (input.legacyFlags?.length) return blocked("legacy_rebind_required");
1272
+ if (input.authorityDisposition === "conditional_wait") return blocked("awaiting_root_condition");
1273
+ if (input.waitAuthorization !== void 0) return blocked("awaiting_root_wait");
1274
+ if (input.authorityDisposition === "human_actor") return blocked("human_executor");
1275
+ if (input.targetCaptureStatus !== void 0 && input.targetCaptureStatus !== "resolved") return blocked("target_clarification_required");
1276
+ if (input.targetSourceKind === "environment_default") return blocked("target_environment_default");
1277
+ if (input.resolvedTarget !== void 0 && input.targetAuthorizes === false) return {
1278
+ ...blocked("target_not_authorizing"),
1279
+ targetCompatible: false
1280
+ };
1281
+ if (input.conflictingProhibition) return blocked("conflicting_prohibition");
1282
+ if (input.adapterSupported === false && isStatefulAction(input.action)) return blocked("adapter_unavailable");
1283
+ if (input.holdsExecutionAuthority === false) return blocked("item_not_executable");
1284
+ return {
1285
+ ...base,
1286
+ status: "compatible",
1287
+ reasonCodes: [],
1288
+ semanticsCompatible: true,
1289
+ targetCompatible: true
1290
+ };
1291
+ }
1292
+ /**
1293
+ * Whether the installed cohort can certify this action at all. Kept separate
1294
+ * from {@link evaluateCompatibility} so a caller never reads a capability gap
1295
+ * as a permission or an interpretation problem.
1296
+ */
1297
+ function actionHasAdapter(action) {
1298
+ if (!isStatefulAction(action)) return true;
1299
+ return ACTION_MANIFEST.actions[action].evidenceProducer === "supported";
1300
+ }
1301
+
1127
1302
  //#endregion
1128
1303
  //#region src/tools/prepare.ts
1304
+ /**
1305
+ * Whether a standing prohibition the gate would refuse now covers this
1306
+ * hypothesis. It mirrors `authorizeMutationFromProjection`'s own check: a
1307
+ * pending, root-authorized, non-legacy prohibition on the same action whose
1308
+ * declared identity matches the target this preparation is about.
1309
+ */
1310
+ function conflictsWithProhibition(projection, action, item) {
1311
+ const resolved = item.requestedTarget;
1312
+ if (resolved === void 0) return false;
1313
+ return [...projection.items.values()].some((candidate) => candidate.status === "pending" && candidate.kind === "prohibition" && (candidate.authority === "root_instruction" || candidate.authority === "root_adoption") && !candidate.legacyFlags?.length && candidate.semanticAction === action && requestedTargetMatchesResolved(action, candidate.requestedTarget, resolved));
1314
+ }
1129
1315
  /** Discovery pages stay bounded like checkpoint pages. */
1130
1316
  const DISCOVERY_ITEM_LIMIT = 8;
1131
1317
  const encodeCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
@@ -1139,8 +1325,10 @@ const encodeCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toS
1139
1325
  * are reached by item ID, not re-listed here (0.6.1, W060-03).
1140
1326
  */
1141
1327
  function discoveryItemIds(p) {
1328
+ const current = currentV6Feedback(p);
1329
+ if (current && current.status !== "unknown") return current.openIds;
1142
1330
  const pending = [...p.items.values()].filter((item) => item.status === "pending").sort((a, b) => a.revision - b.revision || a.id.localeCompare(b.id));
1143
- if (p.boundaryProtocol !== 5) return pending.map((item) => item.id);
1331
+ if (p.boundaryProtocol === void 0 || p.boundaryProtocol < 5) return pending.map((item) => item.id);
1144
1332
  const closureUnits = new Set([...p.currentUnitId !== void 0 ? [p.currentUnitId, ...unitDescendantIds(p, p.currentUnitId)] : []]);
1145
1333
  return pending.filter((item) => item.unitId === void 0 || item.unitId !== void 0 && closureUnits.has(item.unitId)).map((item) => item.id);
1146
1334
  }
@@ -1156,7 +1344,7 @@ function discoveryItemIds(p) {
1156
1344
  function createPrepareTool(options) {
1157
1345
  return defineTool({
1158
1346
  name: "context_guard_prepare",
1159
- description: "Read-only pre-action preparation: report the supported command shape, required evidence order, existing references, and exact missing target fields for one contract item. Omit item_id to list current open items with their IDs; a stateful change needs resolution/effect/state, a read-only verification needs one matching fact. Pagination follows page_cursor (bound to the contract revision) and semantic_action filters the listing. Performs no action and grants no authority.",
1347
+ description: "Read-only diagnosis of open contract items. Ordinary changes use native host tools and observed facts; this tool never grants execution permission. Omit item_id for a paginated item list.",
1160
1348
  parameters: {
1161
1349
  item_id: { type: "string" },
1162
1350
  item_revision: { type: "number" },
@@ -1197,8 +1385,66 @@ function createPrepareTool(options) {
1197
1385
  status: "unknown",
1198
1386
  reason_code: "guard_unavailable"
1199
1387
  };
1388
+ const currentFeedback = currentV6Feedback(p);
1389
+ if (currentFeedback?.status === "unknown") return {
1390
+ status: "unknown",
1391
+ reason_code: currentFeedback.reasonCode
1392
+ };
1393
+ if (p.boundaryProtocol === 6 && args.item_id !== void 0) {
1394
+ const sourced = currentFeedback ? sourceItemForCoreRequirement(p, args.item_id) : void 0;
1395
+ const current = sourced?.item ?? p.items.get(args.item_id);
1396
+ if (!current) return {
1397
+ status: "rejected",
1398
+ reason_code: "item_not_found"
1399
+ };
1400
+ if (args.item_revision !== void 0 && args.item_revision !== current.revision) return {
1401
+ status: "rejected",
1402
+ reason_code: "item_revision_mismatch"
1403
+ };
1404
+ if (current.kind === "prohibition" && currentFeedback) {
1405
+ const state = currentFeedback.predicates[args.item_id];
1406
+ if (state === "constraint_active" || state === "constraint_unresolved" || state === "constraint_violated") return {
1407
+ status: state === "constraint_active" ? "active" : state === "constraint_unresolved" ? "unknown" : "incomplete",
1408
+ reason_code: state,
1409
+ item: {
1410
+ id: current.id,
1411
+ revision: current.revision,
1412
+ status: state
1413
+ },
1414
+ next_step: state === "constraint_active" ? "This sourced prohibition remains active." : state === "constraint_unresolved" ? "The current Host facts cannot establish whether this prohibition was respected." : "A sourced Host mutation violated this prohibition."
1415
+ };
1416
+ }
1417
+ if (current.semanticAction !== "publish" && currentFeedback) {
1418
+ const exactDerived = sourced?.origin !== void 0;
1419
+ const related = Object.entries(currentFeedback.predicates).filter(([id]) => exactDerived ? id === args.item_id : id === args.item_id || sourceItemForCoreRequirement(p, id)?.item.id === current.id);
1420
+ const state = related.length === 0 ? void 0 : related.every(([, value]) => value === "satisfied") ? "satisfied" : "insufficient";
1421
+ return {
1422
+ status: state === void 0 || state === "satisfied" ? "observed" : "incomplete",
1423
+ reason_code: state === void 0 ? "historical_item_not_current" : state === "satisfied" ? "ordinary_current_predicate_observed" : "current_predicate_insufficient",
1424
+ item: {
1425
+ id: args.item_id,
1426
+ source_item_id: current.id,
1427
+ revision: current.revision,
1428
+ status: state ?? "historical",
1429
+ related_requirement_ids: related.map(([id]) => id)
1430
+ },
1431
+ next_step: state === void 0 ? "This item is historical and is not current ordinary work." : state === "satisfied" ? "This ordinary predicate is already observed. Continue with the remaining sourced requirements; no Guard execution qualification is needed." : "Use the current sourced action and host facts; no Guard execution qualification is needed."
1432
+ };
1433
+ }
1434
+ if (current.semanticAction !== "publish") return {
1435
+ status: "observed",
1436
+ reason_code: "ordinary_execution_host_owned",
1437
+ item: {
1438
+ id: current.id,
1439
+ revision: current.revision,
1440
+ status: current.status
1441
+ },
1442
+ next_step: "Use the host tool for ordinary work. Guard can observe its persisted result and independent readback; no Guard preparation or qualification is required."
1443
+ };
1444
+ }
1200
1445
  if (args.item_id === void 0) {
1201
1446
  const filter = args.semantic_action ?? null;
1447
+ const coreIdentity = currentFeedback ? sha256(JSON.stringify(p.coreV2 ?? null)) : void 0;
1202
1448
  const invalidCursor = (reason_code, note) => ({
1203
1449
  status: "rejected",
1204
1450
  reason_code,
@@ -1212,18 +1458,23 @@ function createPrepareTool(options) {
1212
1458
  try {
1213
1459
  if (args.page_cursor.length <= 1024) {
1214
1460
  const value = JSON.parse(Buffer.from(args.page_cursor, "base64url").toString("utf8"));
1215
- if (value?.v === 1 && Number.isSafeInteger(value.r) && (value.f === null || typeof value.f === "string") && Array.isArray(value.k) && Number.isSafeInteger(value.k[0]) && typeof value.k[1] === "string") parsed = value;
1461
+ if (value?.v === 1 && Number.isSafeInteger(value.r) && (value.f === null || typeof value.f === "string") && Array.isArray(value.k) && Number.isSafeInteger(value.k[0]) && typeof value.k[1] === "string" && (value.c === void 0 || typeof value.c === "string")) parsed = value;
1216
1462
  }
1217
1463
  } catch {
1218
1464
  parsed = void 0;
1219
1465
  }
1220
1466
  if (!parsed) return invalidCursor("discovery_cursor_malformed");
1221
1467
  if (parsed.r !== p.contractRevision) return invalidCursor("discovery_cursor_stale", `The contract changed (cursor revision ${parsed.r}, current ${p.contractRevision}). Re-run discovery without page_cursor; items are never skipped by a stale page.`);
1468
+ if (parsed.c !== coreIdentity) return invalidCursor("discovery_cursor_stale", "The current observation changed. Re-run discovery without page_cursor.");
1222
1469
  if ((parsed.f ?? null) !== (filter ?? null)) return invalidCursor("discovery_cursor_filter_mismatch");
1223
1470
  startAfter = parsed.k;
1224
1471
  }
1225
- const eligible = discoveryItemIds(p).map((id) => p.items.get(id)).filter((item$1) => filter === null || (item$1.semanticAction ?? "generic_run") === filter);
1226
- const startIndex = startAfter === void 0 ? 0 : eligible.findIndex((item$1) => item$1.revision === startAfter[0] && item$1.id === startAfter[1]) + 1;
1472
+ const eligible = discoveryItemIds(p).map((id) => ({
1473
+ id,
1474
+ sourced: currentFeedback ? sourceItemForCoreRequirement(p, id) : void 0,
1475
+ item: currentFeedback ? sourceItemForCoreRequirement(p, id)?.item : p.items.get(id)
1476
+ })).filter((entry) => entry.item !== void 0).filter(({ item: item$1, sourced }) => filter === null || (sourced?.origin?.action ?? item$1.semanticAction ?? "generic_run") === filter);
1477
+ const startIndex = startAfter === void 0 ? 0 : eligible.findIndex(({ id, item: item$1 }) => item$1.revision === startAfter[0] && id === startAfter[1]) + 1;
1227
1478
  if (startAfter !== void 0 && startIndex <= 0) return invalidCursor("discovery_cursor_stale", "The cursor names an item no longer in the current listing. Re-run discovery without page_cursor.");
1228
1479
  const page = eligible.slice(startIndex, startIndex + DISCOVERY_ITEM_LIMIT);
1229
1480
  const hasMore = startIndex + page.length < eligible.length;
@@ -1235,15 +1486,21 @@ function createPrepareTool(options) {
1235
1486
  total_open: eligible.length,
1236
1487
  listed: page.length,
1237
1488
  has_more: hasMore,
1238
- items: page.map((item$1) => {
1489
+ items: page.map(({ id, item: item$1, sourced }) => {
1239
1490
  const diagnosis$1 = deriveItemDiagnosis(p, item$1);
1240
1491
  return {
1241
- id: item$1.id,
1492
+ id,
1493
+ ...sourced?.origin ? {
1494
+ source_item_id: item$1.id,
1495
+ source_start: sourced.origin.sourceStart,
1496
+ source_end: sourced.origin.sourceEnd,
1497
+ target: sourced.origin.target
1498
+ } : {},
1242
1499
  revision: item$1.revision,
1243
1500
  kind: item$1.kind,
1244
1501
  ...item$1.taskKind !== void 0 ? { task_kind: item$1.taskKind } : {},
1245
- semantic_action: item$1.semanticAction ?? "generic_run",
1246
- reason_code: diagnosis$1.reason_code,
1502
+ semantic_action: sourced?.origin?.action ?? item$1.semanticAction ?? "generic_run",
1503
+ reason_code: currentFeedback ? currentFeedback.predicates[id] ?? "current_predicate_insufficient" : diagnosis$1.reason_code,
1247
1504
  text: item$1.normalizedText
1248
1505
  };
1249
1506
  }),
@@ -1251,10 +1508,11 @@ function createPrepareTool(options) {
1251
1508
  v: 1,
1252
1509
  r: p.contractRevision,
1253
1510
  f: filter,
1254
- k: [page[page.length - 1].revision, page[page.length - 1].id]
1511
+ k: [page[page.length - 1].item.revision, page[page.length - 1].id],
1512
+ ...coreIdentity ? { c: coreIdentity } : {}
1255
1513
  }) } : {},
1256
1514
  ...filter !== null ? { filtered_by: { semantic_action: filter } } : {},
1257
- note: "Re-run with one item_id to prepare that item, or pass page_cursor for the next page. Preparation performs no action."
1515
+ note: "Re-run with one item_id for a read-only diagnosis, or pass page_cursor for the next page."
1258
1516
  };
1259
1517
  }
1260
1518
  const item = p.items.get(args.item_id ?? "");
@@ -1268,12 +1526,76 @@ function createPrepareTool(options) {
1268
1526
  item_revision: item.revision
1269
1527
  };
1270
1528
  const diagnosis = deriveItemDiagnosis(p, item);
1529
+ const itemAction = item.semanticAction ?? "generic_run";
1271
1530
  const plannedAction = args.semantic_action ?? item.semanticAction;
1272
1531
  const manifestEntry = plannedAction ? ACTION_MANIFEST.actions[plannedAction] : void 0;
1273
1532
  if (plannedAction && !manifestEntry) return {
1274
1533
  status: "rejected",
1275
1534
  reason_code: "unsupported_action"
1276
1535
  };
1536
+ const compatibility = evaluateCompatibility({
1537
+ action: plannedAction ?? itemAction,
1538
+ itemAction,
1539
+ itemRevision: args.item_revision,
1540
+ currentRevision: item.revision,
1541
+ enabled: p.enabled,
1542
+ integrity: p.integrity,
1543
+ hostStatus: p.hostStatus,
1544
+ itemKind: item.kind,
1545
+ itemStatus: item.status,
1546
+ authority: item.authority,
1547
+ legacyFlags: item.legacyFlags,
1548
+ authorityDisposition: item.authorityDisposition,
1549
+ holdsExecutionAuthority: itemHoldsExecutionAuthority(item),
1550
+ waitAuthorization: item.waitAuthorization,
1551
+ reboundFrom: item.reboundFrom,
1552
+ originalAuthority: item.reboundFrom ? (() => {
1553
+ const original = p.items.get(item.reboundFrom.itemId);
1554
+ return original ? {
1555
+ semanticAction: original.semanticAction,
1556
+ requestedTarget: original.requestedTarget
1557
+ } : void 0;
1558
+ })() : void 0,
1559
+ targetCaptureStatus: item.targetCaptureStatus,
1560
+ targetSourceKind: item.targetSource?.kind,
1561
+ requestedTarget: item.requestedTarget,
1562
+ ...args.requested_target !== void 0 ? { resolvedTarget: args.requested_target } : item.requestedTarget ? { resolvedTarget: item.requestedTarget } : {},
1563
+ ...item.requestedTarget !== void 0 ? { targetAuthorizes: plannedAction !== void 0 && isStatefulAction(plannedAction) ? requestedTargetAuthorizesMutation(plannedAction, item.requestedTarget, args.requested_target ?? item.requestedTarget) : true } : {},
1564
+ conflictingProhibition: plannedAction !== void 0 && isStatefulAction(plannedAction) && conflictsWithProhibition(p, plannedAction, item),
1565
+ adapterSupported: actionHasAdapter(plannedAction ?? itemAction)
1566
+ }, (requested, resolved) => plannedAction !== void 0 && isStatefulAction(plannedAction) ? requestedTargetMatchesResolved(plannedAction, requested, resolved) : true);
1567
+ const compatibilityView = {
1568
+ status: compatibility.status,
1569
+ assumed_action: compatibility.assumedAction,
1570
+ ...compatibility.itemAction !== void 0 ? { item_action: compatibility.itemAction } : {},
1571
+ reason_codes: compatibility.reasonCodes,
1572
+ semantics_compatible: compatibility.semanticsCompatible,
1573
+ target_compatible: compatibility.targetCompatible,
1574
+ certifiable: compatibility.certifiable,
1575
+ ...compatibility.requiredIdentityField !== void 0 ? { required_identity_field: compatibility.requiredIdentityField } : {},
1576
+ note: compatibility.status === "compatible" ? "This assumption matches the current obligation. Preparation itself still grants no authority." : compatibility.status === "incompatible" ? "This assumption is not what this obligation records. Prepare again with the item action, or record a fresh root instruction that authorizes the action you intended." : "This assumption matches the obligation, but this snapshot cannot execute yet. Clear the named condition first."
1577
+ };
1578
+ if (compatibility.status === "incompatible") return {
1579
+ status: "incompatible",
1580
+ item: {
1581
+ id: item.id,
1582
+ revision: item.revision
1583
+ },
1584
+ diagnosis,
1585
+ compatibility: compatibilityView,
1586
+ reason_code: compatibility.reasonCodes[0],
1587
+ note: compatibilityView.note
1588
+ };
1589
+ const recipe = plannedAction && isStatefulAction(plannedAction) ? actionPreparation(plannedAction) : void 0;
1590
+ const missingTargetFields = recipe ? recipe.selector_fields.filter((key) => !(item.requestedTarget?.[key] !== void 0 || args.requested_target?.[key] !== void 0)) : [];
1591
+ const callerTargetProposedKeys = item.targetCaptureStatus === "resolved" ? Object.keys(args.requested_target ?? {}).filter((key) => {
1592
+ const own = item.requestedTarget?.[key];
1593
+ const selectedByItem = own !== void 0;
1594
+ const plannedByRecipe = recipe?.selector_fields.includes(key) === true;
1595
+ if (!selectedByItem && !plannedByRecipe) return false;
1596
+ const proposed = args.requested_target?.[key];
1597
+ return proposed !== own && JSON.stringify(proposed) !== JSON.stringify(own);
1598
+ }) : [];
1277
1599
  const reusable = [...p.evidence.values()].filter((evidence) => relevantEvidence(p, item, evidence) && evidenceAvailabilityReason(evidence) === void 0).sort((a, b) => b.toolResultSeq - a.toolResultSeq).slice(0, 8).map((evidence) => ({
1278
1600
  evidence_id: evidence.id,
1279
1601
  role: evidence.evidenceRole,
@@ -1286,8 +1608,6 @@ function createPrepareTool(options) {
1286
1608
  "effect (the exact planned change)",
1287
1609
  "state (independent post-state readback)"
1288
1610
  ] : ["effect (one matching durable verification fact)"];
1289
- const recipe = plannedAction && isStatefulAction(plannedAction) ? actionPreparation(plannedAction) : void 0;
1290
- const missingTargetFields = recipe ? recipe.selector_fields.filter((key) => !(item.requestedTarget?.[key] !== void 0 || args.requested_target?.[key] !== void 0)) : [];
1291
1611
  const capability = plannedAction && options.hostCapability ? options.hostCapability(plannedAction) : void 0;
1292
1612
  const commandShape = options.commandTemplate && plannedAction ? options.commandTemplate(plannedAction) : void 0;
1293
1613
  return {
@@ -1297,6 +1617,7 @@ function createPrepareTool(options) {
1297
1617
  revision: item.revision
1298
1618
  },
1299
1619
  diagnosis,
1620
+ compatibility: compatibilityView,
1300
1621
  ...plannedAction !== void 0 ? { planned_action: plannedAction } : {},
1301
1622
  ...commandShape !== void 0 ? { supported_command_shape: commandShape } : {},
1302
1623
  required_evidence_order: requiredOrder,
@@ -1306,19 +1627,26 @@ function createPrepareTool(options) {
1306
1627
  status: capability.status,
1307
1628
  ...capability.reasonCode !== void 0 ? { reason_code: capability.reasonCode } : {}
1308
1629
  } } : {},
1309
- ...recipe ? { evidence_input_contract: {
1310
- selector_fields: recipe.selector_fields,
1311
- optional_selector_fields: recipe.optional_selector_fields,
1312
- command_manifest_fields: recipe.command_manifest_fields,
1313
- command_manifest_ids: recipe.command_manifest_ids,
1314
- planned_tools: recipe.planned_tools,
1315
- planned_argument_fields: recipe.planned_argument_fields,
1316
- producer_fields: recipe.producer_fields,
1317
- readback_fields: recipe.readback_fields,
1318
- execution_surface: recipe.execution_surface,
1319
- steps: recipe.steps
1630
+ ...recipe ? {
1631
+ recipe_only: true,
1632
+ evidence_input_contract: {
1633
+ selector_fields: recipe.selector_fields,
1634
+ optional_selector_fields: recipe.optional_selector_fields,
1635
+ command_manifest_fields: recipe.command_manifest_fields,
1636
+ command_manifest_ids: recipe.command_manifest_ids,
1637
+ planned_tools: recipe.planned_tools,
1638
+ planned_argument_fields: recipe.planned_argument_fields,
1639
+ producer_fields: recipe.producer_fields,
1640
+ readback_fields: recipe.readback_fields,
1641
+ execution_surface: recipe.execution_surface,
1642
+ steps: recipe.steps
1643
+ }
1644
+ } : {},
1645
+ ...callerTargetProposedKeys.length > 0 ? { caller_target_is_proposal: {
1646
+ fields: callerTargetProposedKeys,
1647
+ note: "The supplied requested_target differs from the target this obligation selected. It is recorded as the caller's proposal for the plan only; authorization still compares the obligation's own target."
1320
1648
  } } : {},
1321
- note: "Preparation performs no action. A default or guessed target is not user authority; explicit root instruction is required for missing target fields."
1649
+ note: callerTargetProposedKeys.length > 0 ? "Preparation performs no action. The supplied requested_target is NOT the target this obligation selected and is not authority; the recipe below is recipe_only. Resolve the item target through context_guard_evidence before executing." : "Preparation performs no action. A default or guessed target is not user authority; explicit root instruction is required for missing target fields."
1322
1650
  };
1323
1651
  }
1324
1652
  });
@@ -1333,9 +1661,9 @@ function parsePartition(args, extent) {
1333
1661
  if (!Array.isArray(raw)) return void 0;
1334
1662
  const spans = [];
1335
1663
  for (const entry of raw) {
1336
- const record$1 = entry;
1337
- const start = record$1?.start;
1338
- const end = record$1?.end;
1664
+ const record$2 = entry;
1665
+ const start = record$2?.start;
1666
+ const end = record$2?.end;
1339
1667
  if (typeof start !== "number" || !Number.isSafeInteger(start) || typeof end !== "number" || !Number.isSafeInteger(end) || start >= end) return void 0;
1340
1668
  spans.push({
1341
1669
  start,
@@ -1465,7 +1793,7 @@ function createInterpretTool(options) {
1465
1793
 
1466
1794
  //#endregion
1467
1795
  //#region src/tools/evidence.ts
1468
- const execFileAsync = promisify(execFile);
1796
+ const execFileAsync$1 = promisify(execFile);
1469
1797
  const PRODUCER_VERSION = "1.0.0";
1470
1798
  const PRODUCER_TOOL = "context_guard_evidence";
1471
1799
  const ACTION_TOOL = "context_guard_action";
@@ -1484,17 +1812,17 @@ const SUPPORTED = [
1484
1812
  const RESTART_INTENT_PREFIX = "Context Guard restart intent v1: ";
1485
1813
  function restartIntent(events, resolutionCallId, target) {
1486
1814
  for (const raw of events) {
1487
- const event = record(raw);
1815
+ const event = record$1(raw);
1488
1816
  if (!event || event.type !== "user/message") continue;
1489
- const data = record(event.data);
1490
- const source = record(data?.source);
1817
+ const data = record$1(event.data);
1818
+ const source = record$1(data?.source);
1491
1819
  if (source?.kind !== "plugin" || source.plugin !== "context-guard" || source.form !== "notice") continue;
1492
1820
  const content = Array.isArray(data?.content) ? data.content : [];
1493
- const block = content.length === 1 ? record(content[0]) : void 0;
1821
+ const block = content.length === 1 ? record$1(content[0]) : void 0;
1494
1822
  const text = typeof block?.text === "string" ? block.text : "";
1495
1823
  if (!text.startsWith(RESTART_INTENT_PREFIX)) continue;
1496
1824
  try {
1497
- const value = record(JSON.parse(text.slice(33)));
1825
+ const value = record$1(JSON.parse(text.slice(33)));
1498
1826
  if (value?.resolution_call_id === resolutionCallId && value.service_id === target.service_id && value.pre_generation === target.pre_generation) return true;
1499
1827
  } catch {}
1500
1828
  }
@@ -1522,7 +1850,7 @@ function installedProfile(moduleUrl = import.meta.url) {
1522
1850
  directory = parent;
1523
1851
  }
1524
1852
  }
1525
- function record(value) {
1853
+ function record$1(value) {
1526
1854
  return value && typeof value === "object" ? value : void 0;
1527
1855
  }
1528
1856
  function stable(value) {
@@ -1546,7 +1874,7 @@ function jsonExpectedTransition(transition) {
1546
1874
  };
1547
1875
  }
1548
1876
  function tuple(value) {
1549
- return record(value);
1877
+ return record$1(value);
1550
1878
  }
1551
1879
  function adapterId(action) {
1552
1880
  if (["create", "modify"].includes(action)) return "context-guard.artifact.v1";
@@ -1595,29 +1923,29 @@ function supported(action, role, resolved, observed = {}, commandManifest = {},
1595
1923
  };
1596
1924
  }
1597
1925
  function messageMeta(event) {
1598
- return record(record(event.data)?.meta);
1926
+ return record$1(record$1(event.data)?.meta);
1599
1927
  }
1600
1928
  function producerMeta(event) {
1601
- return record(messageMeta(event)?.contextGuard);
1929
+ return record$1(messageMeta(event)?.contextGuard);
1602
1930
  }
1603
1931
  function eventCallId(event) {
1604
- const data = record(event.data);
1932
+ const data = record$1(event.data);
1605
1933
  if (event.type === "tool/call") return typeof data?.callId === "string" ? data.callId : void 0;
1606
- const source = record(record(data?.message)?.source);
1934
+ const source = record$1(record$1(data?.message)?.source);
1607
1935
  return typeof source?.callId === "string" ? source.callId : void 0;
1608
1936
  }
1609
1937
  function findResolution(events, callId, action) {
1610
1938
  let selector;
1611
1939
  let commandManifest;
1612
1940
  for (const raw of events) {
1613
- const event = record(raw);
1941
+ const event = record$1(raw);
1614
1942
  if (!event || eventCallId(event) !== callId) continue;
1615
1943
  if (event.type === "tool/call") {
1616
- const data = record(event.data);
1944
+ const data = record$1(event.data);
1617
1945
  try {
1618
- const args = record(JSON.parse(String(data?.arguments ?? "{}")));
1619
- selector = record(args?.selector);
1620
- commandManifest = record(args?.command_manifest);
1946
+ const args = record$1(JSON.parse(String(data?.arguments ?? "{}")));
1947
+ selector = record$1(args?.selector);
1948
+ commandManifest = record$1(args?.command_manifest);
1621
1949
  } catch {
1622
1950
  return;
1623
1951
  }
@@ -1627,13 +1955,13 @@ function findResolution(events, callId, action) {
1627
1955
  const meta = producerMeta(event);
1628
1956
  if (meta?.semanticAction !== action || meta.evidenceRole !== "resolution" || meta.adapterVersion !== (action === "restart" ? "2.0.0" : PRODUCER_VERSION) || !selector || !commandManifest) return void 0;
1629
1957
  const target = tuple(meta.resolvedTarget);
1630
- const rawBinding = record(meta.gitBinding);
1631
- const rawManifest = record(rawBinding?.manifest);
1632
- const rawPrestate = record(rawBinding?.prestate);
1633
- const rawEnvelope = record(rawBinding?.envelope);
1634
- const rawExecutable = record(meta.executableIdentity);
1635
- const rawExpected = record(meta.expectedTransition);
1636
- const expectedParameters$1 = record(rawExpected?.parameters);
1958
+ const rawBinding = record$1(meta.gitBinding);
1959
+ const rawManifest = record$1(rawBinding?.manifest);
1960
+ const rawPrestate = record$1(rawBinding?.prestate);
1961
+ const rawEnvelope = record$1(rawBinding?.envelope);
1962
+ const rawExecutable = record$1(meta.executableIdentity);
1963
+ const rawExpected = record$1(meta.expectedTransition);
1964
+ const expectedParameters$1 = record$1(rawExpected?.parameters);
1637
1965
  const expectedTransition = rawExpected && typeof rawExpected.predicateId === "string" && rawExpected.version === 1 && rawExpected.predParamsKind === "inline" && expectedParameters$1 ? rawExpected : void 0;
1638
1966
  const expectedTransitionDigest = typeof meta.expectedTransitionDigest === "string" ? meta.expectedTransitionDigest : void 0;
1639
1967
  const interpreterIdentityValid = rawExecutable && (rawExecutable.interpreterRealpath === void 0 && rawExecutable.interpreterVersion === void 0 || typeof rawExecutable.interpreterRealpath === "string" && typeof rawExecutable.interpreterVersion === "string");
@@ -1657,14 +1985,14 @@ function findResolution(events, callId, action) {
1657
1985
  function findEffect(events, callId) {
1658
1986
  let call;
1659
1987
  for (const raw of events) {
1660
- const event = record(raw);
1988
+ const event = record$1(raw);
1661
1989
  if (!event) continue;
1662
1990
  const seq = typeof event.seq === "number" ? event.seq : -1;
1663
1991
  if (event.type === "tool/call" && eventCallId(event) === callId) {
1664
- const data = record(event.data);
1992
+ const data = record$1(event.data);
1665
1993
  let args = {};
1666
1994
  try {
1667
- args = record(JSON.parse(String(data?.arguments ?? "{}"))) ?? {};
1995
+ args = record$1(JSON.parse(String(data?.arguments ?? "{}"))) ?? {};
1668
1996
  } catch {
1669
1997
  args = {};
1670
1998
  }
@@ -1677,23 +2005,26 @@ function findEffect(events, callId) {
1677
2005
  };
1678
2006
  }
1679
2007
  if (event.type === "tool/result" && eventCallId(event) === callId && call) {
1680
- const data = record(event.data);
2008
+ const data = record$1(event.data);
1681
2009
  call.resultSeq = seq;
1682
- call.error = data?.error;
2010
+ call.error = persistedToolResultStatus(data, callId) !== "clean" ? {
2011
+ name: "HostResultError",
2012
+ code: "HOST_RESULT_UNTRUSTED"
2013
+ } : void 0;
1683
2014
  call.meta = data?.meta;
1684
- call.textContent = extractTextContent(record(data?.message)?.content ?? []);
2015
+ call.textContent = extractTextContent(record$1(data?.message)?.content ?? []);
1685
2016
  return call;
1686
2017
  }
1687
2018
  }
1688
2019
  }
1689
2020
  function actionCallMatches(events, callId, action, resolutionCallId, target) {
1690
2021
  for (const raw of events) {
1691
- const event = record(raw);
2022
+ const event = record$1(raw);
1692
2023
  if (!event || event.type !== "tool/call" || eventCallId(event) !== callId) continue;
1693
- const data = record(event.data);
2024
+ const data = record$1(event.data);
1694
2025
  if (data?.name !== ACTION_TOOL) return false;
1695
2026
  try {
1696
- const args = record(JSON.parse(String(data.arguments ?? "{}")));
2027
+ const args = record$1(JSON.parse(String(data.arguments ?? "{}")));
1697
2028
  return args?.semantic_action === action && args.resolution_call_id === resolutionCallId && args.target_digest === digest(target) && typeof args.contract_item_id === "string" && Number.isSafeInteger(args.contract_item_revision);
1698
2029
  } catch {
1699
2030
  return false;
@@ -1703,15 +2034,15 @@ function actionCallMatches(events, callId, action, resolutionCallId, target) {
1703
2034
  }
1704
2035
  function actionResultCompleted(events, callId) {
1705
2036
  for (const raw of events) {
1706
- const event = record(raw);
2037
+ const event = record$1(raw);
1707
2038
  if (!event || event.type !== "tool/result" || eventCallId(event) !== callId) continue;
1708
- return record(messageMeta(event)?.contextGuardAction)?.status === "completed";
2039
+ return record$1(messageMeta(event)?.contextGuardAction)?.status === "completed" && persistedToolResultStatus(event.data, callId) === "clean";
1709
2040
  }
1710
2041
  return false;
1711
2042
  }
1712
2043
  function plannedEffectDigest(manifest) {
1713
2044
  const name$1 = typeof manifest.planned_tool === "string" ? manifest.planned_tool : void 0;
1714
- const args = record(manifest.planned_arguments);
2045
+ const args = record$1(manifest.planned_arguments);
1715
2046
  return name$1 && args ? digest({
1716
2047
  name: name$1,
1717
2048
  arguments: args
@@ -1719,7 +2050,7 @@ function plannedEffectDigest(manifest) {
1719
2050
  }
1720
2051
  function plannedEffect(manifest) {
1721
2052
  const name$1 = typeof manifest.planned_tool === "string" ? manifest.planned_tool : void 0;
1722
- const args = record(manifest.planned_arguments);
2053
+ const args = record$1(manifest.planned_arguments);
1723
2054
  return name$1 && args ? {
1724
2055
  name: name$1,
1725
2056
  arguments: args,
@@ -1752,7 +2083,7 @@ function effectDigest(effect) {
1752
2083
  });
1753
2084
  }
1754
2085
  function cwdOf(agent) {
1755
- const header = record(agent.session.header);
2086
+ const header = record$1(agent.session.header);
1756
2087
  return typeof header?.cwd === "string" ? header.cwd : void 0;
1757
2088
  }
1758
2089
  function pathOf(selector, cwd) {
@@ -1770,7 +2101,7 @@ async function fileDigest(path) {
1770
2101
  }
1771
2102
  async function readJson(path) {
1772
2103
  try {
1773
- return record(JSON.parse(await readFile(path, "utf8")));
2104
+ return record$1(JSON.parse(await readFile(path, "utf8")));
1774
2105
  } catch {
1775
2106
  return;
1776
2107
  }
@@ -1794,7 +2125,7 @@ async function tgzIdentity(path) {
1794
2125
  if (name$1 === "package/package.json") {
1795
2126
  if (manifest || size$1 > 1024 * 1024) return void 0;
1796
2127
  try {
1797
- manifest = record(JSON.parse(tar.subarray(bodyStart, bodyEnd).toString("utf8")));
2128
+ manifest = record$1(JSON.parse(tar.subarray(bodyStart, bodyEnd).toString("utf8")));
1798
2129
  } catch {
1799
2130
  return;
1800
2131
  }
@@ -1804,7 +2135,7 @@ async function tgzIdentity(path) {
1804
2135
  if (typeof manifest?.name !== "string" || typeof manifest.version !== "string") return void 0;
1805
2136
  const gitHead = typeof manifest.gitHead === "string" && /^[0-9a-f]{40}$/.test(manifest.gitHead) ? manifest.gitHead : void 0;
1806
2137
  const repositoryField = manifest.repository;
1807
- const repository = typeof repositoryField === "string" ? repositoryField : record(repositoryField) && typeof record(repositoryField)?.url === "string" ? String(record(repositoryField).url) : void 0;
2138
+ const repository = typeof repositoryField === "string" ? repositoryField : record$1(repositoryField) && typeof record$1(repositoryField)?.url === "string" ? String(record$1(repositoryField).url) : void 0;
1808
2139
  return {
1809
2140
  name: manifest.name,
1810
2141
  version: manifest.version,
@@ -1872,10 +2203,10 @@ async function marketCapabilities(roots, signal) {
1872
2203
  redirect: "error"
1873
2204
  });
1874
2205
  if (!response.ok) return void 0;
1875
- const value = record(await response.json());
2206
+ const value = record$1(await response.json());
1876
2207
  if (value?.schema !== MARKET_SCHEMA || value.apiVersion !== 1 || value.marketVersion !== binding.version || value.profile !== binding.profile || value.bootId !== binding.bootId) return void 0;
1877
- const features = record(value.features);
1878
- const restart = record(value.restart);
2208
+ const features = record$1(value.features);
2209
+ const restart = record$1(value.restart);
1879
2210
  if (features?.restart !== true || restart?.supported !== true || restart.managedBy !== "market") return void 0;
1880
2211
  const provider = createHash("sha256").update(JSON.stringify([
1881
2212
  MARKET_SCHEMA,
@@ -1939,17 +2270,17 @@ async function profilePackage(profilePath, packageId) {
1939
2270
  }
1940
2271
  }
1941
2272
  async function registryIntegrity(registry, packageId, version, roots, signal) {
1942
- const canonical = canonicalRegistryBase(registry, { allowLoopbackHttp: roots.allowLoopbackHttpRegistry });
1943
- if (!canonical || canonical !== registry) return void 0;
1944
- const response = await (roots.fetcher ?? fetch)(new URL(npmEscapedPackageName(packageId), canonical), {
2273
+ const canonical$1 = canonicalRegistryBase(registry, { allowLoopbackHttp: roots.allowLoopbackHttpRegistry });
2274
+ if (!canonical$1 || canonical$1 !== registry) return void 0;
2275
+ const response = await (roots.fetcher ?? fetch)(new URL(npmEscapedPackageName(packageId), canonical$1), {
1945
2276
  signal,
1946
2277
  headers: { accept: "application/json" },
1947
2278
  redirect: "error"
1948
2279
  });
1949
2280
  if (!response.ok) return void 0;
1950
- const value = record(await response.json());
1951
- const release = record(record(value?.versions)?.[version]);
1952
- const dist = record(release?.dist);
2281
+ const value = record$1(await response.json());
2282
+ const release = record$1(record$1(value?.versions)?.[version]);
2283
+ const dist = record$1(release?.dist);
1953
2284
  return value?.name === packageId && release?.name === packageId && release.version === version && typeof dist?.integrity === "string" ? dist.integrity : void 0;
1954
2285
  }
1955
2286
  function windowsBatchCommand(file, args) {
@@ -1965,7 +2296,7 @@ async function windowsCommandInterpreter(signal) {
1965
2296
  const interpreterRealpath = await realpath(configured);
1966
2297
  const systemInterpreter = await realpath(resolve(systemRoot, "System32", "cmd.exe"));
1967
2298
  if (basename(interpreterRealpath).toLowerCase() !== "cmd.exe" || interpreterRealpath.toLowerCase() !== systemInterpreter.toLowerCase()) return void 0;
1968
- const { stdout, stderr } = await execFileAsync(interpreterRealpath, [
2299
+ const { stdout, stderr } = await execFileAsync$1(interpreterRealpath, [
1969
2300
  "/d",
1970
2301
  "/v:off",
1971
2302
  "/c",
@@ -1988,7 +2319,7 @@ async function execAuditedFile(file, args, options, interpreter) {
1988
2319
  if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(file)) {
1989
2320
  const command = windowsBatchCommand(file, args);
1990
2321
  if (!command || !interpreter) throw new Error("unsafe Windows batch invocation");
1991
- return execFileAsync(interpreter.interpreterRealpath, [
2322
+ return execFileAsync$1(interpreter.interpreterRealpath, [
1992
2323
  "/d",
1993
2324
  "/v:off",
1994
2325
  "/s",
@@ -2001,7 +2332,7 @@ async function execAuditedFile(file, args, options, interpreter) {
2001
2332
  windowsVerbatimArguments: true
2002
2333
  });
2003
2334
  }
2004
- return execFileAsync(file, args, {
2335
+ return execFileAsync$1(file, args, {
2005
2336
  ...options,
2006
2337
  encoding: "utf8"
2007
2338
  });
@@ -2037,14 +2368,14 @@ async function executableIdentity(executable, signal) {
2037
2368
  const candidate = resolve(directory, `${executable}${suffix}`);
2038
2369
  try {
2039
2370
  await access(candidate, constants.X_OK);
2040
- const canonical = await realpath(candidate);
2041
- const interpreter = process.platform === "win32" && /\.(?:cmd|bat)$/i.test(canonical) ? await windowsCommandInterpreter(signal) : void 0;
2042
- if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(canonical) && !interpreter) continue;
2043
- const { stdout, stderr } = await execAuditedFile(canonical, ["--version"], { signal }, interpreter);
2371
+ const canonical$1 = await realpath(candidate);
2372
+ const interpreter = process.platform === "win32" && /\.(?:cmd|bat)$/i.test(canonical$1) ? await windowsCommandInterpreter(signal) : void 0;
2373
+ if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(canonical$1) && !interpreter) continue;
2374
+ const { stdout, stderr } = await execAuditedFile(canonical$1, ["--version"], { signal }, interpreter);
2044
2375
  const version = `${stdout}${stderr}`.trim();
2045
2376
  if (version && !version.includes("\n") && !version.includes("\r")) return {
2046
2377
  executable,
2047
- realpath: canonical,
2378
+ realpath: canonical$1,
2048
2379
  version,
2049
2380
  ...interpreter
2050
2381
  };
@@ -2084,8 +2415,8 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
2084
2415
  const capabilities = await marketCapabilities(roots, signal);
2085
2416
  if (!capabilities || !roots.marketOrigin || !resolutionCallId || !agent) return { status: "unavailable" };
2086
2417
  if (!sameMarketProvider(target.pre_generation, capabilities.generation)) return { status: "unavailable" };
2087
- if (capabilities.generation !== target.pre_generation) return restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target) ? { status: "completed" } : { status: "unavailable" };
2088
- if (restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target)) return { status: "handoff_pending" };
2418
+ if (capabilities.generation !== target.pre_generation) return roots.hasRestartIntent?.(resolutionCallId, String(target.service_id), String(target.pre_generation)) || restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target) ? { status: "completed" } : { status: "unavailable" };
2419
+ if (roots.hasRestartIntent?.(resolutionCallId, String(target.service_id), String(target.pre_generation)) || restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target)) return { status: "handoff_pending" };
2089
2420
  if (!roots.persistRestartIntent || !await roots.persistRestartIntent(agent, {
2090
2421
  resolutionCallId,
2091
2422
  serviceId: String(target.service_id),
@@ -2103,7 +2434,7 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
2103
2434
  body: "{}"
2104
2435
  });
2105
2436
  if (!response.ok) return { status: "unavailable" };
2106
- return record(await response.json())?.schema === MARKET_SCHEMA ? { status: "handoff_pending" } : { status: "unavailable" };
2437
+ return record$1(await response.json())?.schema === MARKET_SCHEMA ? { status: "handoff_pending" } : { status: "unavailable" };
2107
2438
  }
2108
2439
  if (action === "commit" || action === "push" || action === "pull" || action === "fetch") {
2109
2440
  const binding = resolution.gitBinding;
@@ -2156,7 +2487,7 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
2156
2487
  return { status: "unavailable" };
2157
2488
  }
2158
2489
  async function gitBytes(repository, args, signal, file = "git") {
2159
- const { stdout } = await execFileAsync(file, args, {
2490
+ const { stdout } = await execFileAsync$1(file, args, {
2160
2491
  cwd: repository,
2161
2492
  encoding: "buffer",
2162
2493
  signal,
@@ -2276,12 +2607,12 @@ function pickTarget(target, keys) {
2276
2607
  async function expectedTransitionForResolution(action, target, commandManifest) {
2277
2608
  let parameters;
2278
2609
  if (action === "create") {
2279
- const plannedArguments = record(commandManifest.planned_arguments);
2610
+ const plannedArguments = record$1(commandManifest.planned_arguments);
2280
2611
  const content = typeof plannedArguments?.content === "string" ? plannedArguments.content : void 0;
2281
2612
  if (content === void 0) return void 0;
2282
2613
  parameters = { post_digest: createHash("sha256").update(Buffer.from(content, "utf8")).digest("hex") };
2283
2614
  } else if (action === "modify") {
2284
- const plannedArguments = record(commandManifest.planned_arguments);
2615
+ const plannedArguments = record$1(commandManifest.planned_arguments);
2285
2616
  const oldString = requireString(plannedArguments ?? {}, "old_string");
2286
2617
  const newString = typeof plannedArguments?.new_string === "string" ? plannedArguments.new_string : void 0;
2287
2618
  const artifact = typeof target.artifact_id === "string" ? target.artifact_id : void 0;
@@ -2358,8 +2689,8 @@ async function resolveTarget(action, selector, commandManifest, cwd, roots, sign
2358
2689
  const service = requireString(selector, "service_id");
2359
2690
  if (service !== "dsh-web" || commandManifest.manifest_id !== "dshmarket.restart.v1" || !ACTION_MANIFEST.actions.restart.commandManifestIds.includes("dshmarket.restart.v1") || Object.keys(commandManifest).length !== 1) return void 0;
2360
2691
  const capabilities = await marketCapabilities(roots, signal);
2361
- const features = record(capabilities?.features);
2362
- const restart = record(capabilities?.restart);
2692
+ const features = record$1(capabilities?.features);
2693
+ const restart = record$1(capabilities?.restart);
2363
2694
  if (features?.restart !== true || restart?.supported !== true || restart.managedBy !== "market") return void 0;
2364
2695
  return { target: {
2365
2696
  service_id: service,
@@ -2588,6 +2919,7 @@ function normalizedRoots(options) {
2588
2919
  ...options.fetcher ? { fetcher: options.fetcher } : {},
2589
2920
  ...options.commandRunner ? { commandRunner: options.commandRunner } : {},
2590
2921
  ...options.persistRestartIntent ? { persistRestartIntent: options.persistRestartIntent } : {},
2922
+ ...options.hasRestartIntent ? { hasRestartIntent: options.hasRestartIntent } : {},
2591
2923
  ...options.hostCapability ? { hostCapability: options.hostCapability } : {},
2592
2924
  ...options.authorizeMutation ? { authorizeMutation: options.authorizeMutation } : {},
2593
2925
  ...options.prepareMutation ? { prepareMutation: options.prepareMutation } : {},
@@ -2601,7 +2933,7 @@ function createActionTool(options = {}) {
2601
2933
  const roots = normalizedRoots(options);
2602
2934
  return defineTool({
2603
2935
  name: ACTION_TOOL,
2604
- description: "Execute one explicit Guard-owned mutation after re-reading a persisted resolution and exact target digest. This tool changes package, Git, registry, or Web service state; its result echoes the bounded target and command-manifest digest.",
2936
+ description: "Compatibility entry for older sessions. Ordinary mutations return a migration diagnosis without side effects; only an explicitly adopted registry publication can use the controlled release path.",
2605
2937
  parameters: {
2606
2938
  semantic_action: {
2607
2939
  type: "string",
@@ -2689,6 +3021,11 @@ function createActionTool(options = {}) {
2689
3021
  target_digest: "",
2690
3022
  command_manifest_digest: ""
2691
3023
  };
3024
+ if (action !== "publish") return {
3025
+ status: "unavailable",
3026
+ reason_code: "ordinary_action_migrated_to_host_tools",
3027
+ ...empty
3028
+ };
2692
3029
  if (!agent || ![
2693
3030
  "install",
2694
3031
  "apply",
@@ -2857,7 +3194,7 @@ function createEvidenceTool(options = {}) {
2857
3194
  const roots = normalizedRoots(options);
2858
3195
  return defineTool({
2859
3196
  name: PRODUCER_TOOL,
2860
- description: "Create one trusted stateful resolution/effect/state fact from the live resource and persisted DSH tool events. Unsupported adapters fail closed.",
3197
+ description: "Observe a controlled registry publish. Ordinary work uses native host tools and read-only observers; older producer calls return migration diagnostics.",
2861
3198
  parameters: {
2862
3199
  semantic_action: {
2863
3200
  type: "string",
@@ -3063,6 +3400,17 @@ function createEvidenceTool(options = {}) {
3063
3400
  async execute(args, exec) {
3064
3401
  const action = args.semantic_action;
3065
3402
  const role = args.evidence_role;
3403
+ if ([
3404
+ "install",
3405
+ "apply",
3406
+ "create",
3407
+ "modify",
3408
+ "restart",
3409
+ "commit",
3410
+ "push",
3411
+ "pull",
3412
+ "fetch"
3413
+ ].includes(action)) return unavailable(action, role, "ordinary_evidence_migrated_to_host_facts", void 0, "Use the native host tool and its persisted result; request only a read-only Guard observer when an independent state fact is needed. Do not repeat an earlier effect.");
3066
3414
  if (!SUPPORTED.includes(action)) return unavailable(action, role, "adapter_unavailable_for_pinned_host");
3067
3415
  if (roots.hostCapability?.(action).status !== "supported" && roots.hostCapability) return unavailable(action, role, "host_capability_unavailable");
3068
3416
  const agent = exec.agent;
@@ -3071,9 +3419,9 @@ function createEvidenceTool(options = {}) {
3071
3419
  if (role === "resolution") {
3072
3420
  const recipe = actionPreparation(action);
3073
3421
  {
3074
- const manifest = record(args.command_manifest);
3075
- const plannedArgs = record(manifest?.planned_arguments);
3076
- const selector = record(args.selector);
3422
+ const manifest = record$1(args.command_manifest);
3423
+ const plannedArgs = record$1(manifest?.planned_arguments);
3424
+ const selector = record$1(args.selector);
3077
3425
  const needsManifestId = [
3078
3426
  "install",
3079
3427
  "apply",
@@ -3093,10 +3441,10 @@ function createEvidenceTool(options = {}) {
3093
3441
  const executable$1 = executableFor(action);
3094
3442
  const executableBinding = executable$1 ? await (roots.readExecutableIdentity ?? executableIdentity)(executable$1, exec.signal) : void 0;
3095
3443
  if (executable$1 && !executableBinding) return unavailable(action, role, "executable_identity_unavailable");
3096
- const resolved = await resolveTarget(action, record(args.selector) ?? {}, record(args.command_manifest) ?? {}, cwdOf(agent), roots, exec.signal, executableBinding);
3444
+ const resolved = await resolveTarget(action, record$1(args.selector) ?? {}, record$1(args.command_manifest) ?? {}, cwdOf(agent), roots, exec.signal, executableBinding);
3097
3445
  if (!resolved) return unavailable(action, role, action === "restart" && !roots.verifyMarketInstance ? "market_instance_binding_unavailable" : "resolution_unavailable");
3098
3446
  const gitBinding = resolved.gitBinding ? JSON.parse(JSON.stringify(resolved.gitBinding)) : void 0;
3099
- const commandManifest = record(args.command_manifest) ?? {};
3447
+ const commandManifest = record$1(args.command_manifest) ?? {};
3100
3448
  const expectedTransition = await expectedTransitionForResolution(action, resolved.target, commandManifest);
3101
3449
  if (!expectedTransition) return unavailable(action, role, "expected_transition_unavailable");
3102
3450
  return supported(action, role, resolved.target, {}, commandManifest, gitBinding, executableBinding, expectedTransition);
@@ -3188,21 +3536,27 @@ function createReleaseTool(options) {
3188
3536
  operations: releaseCoverage(contract$1),
3189
3537
  candidate: contract$1.candidate
3190
3538
  })),
3191
- reservations: projection.releaseReservations.map(({ contractId: contractId$1, operation: operation$1, callId: callId$1, startedAtSeq, observedArtifactSri }) => ({
3539
+ reservations: projection.releaseReservations.map(({ contractId: contractId$1, operation: operation$1, callId: callId$1, startedAtSeq, ledgerPosition, observedArtifactSri }) => ({
3192
3540
  contract_id: contractId$1,
3193
3541
  operation: operation$1,
3194
3542
  resolution_call_id: callId$1,
3195
- started_at_seq: startedAtSeq,
3543
+ ...ledgerPosition === void 0 ? { started_at_seq: startedAtSeq } : { record_position: {
3544
+ channel: "private_ledger",
3545
+ position: ledgerPosition
3546
+ } },
3196
3547
  observed_artifact_sri: observedArtifactSri ?? null,
3197
3548
  in_flight: inFlightReservation(projection, contractId$1, operation$1)?.callId === callId$1
3198
3549
  })),
3199
- settlements: projection.releaseSettlements.map(({ contractId: contractId$1, operation: operation$1, callId: callId$1, outcome: outcome$1, readback: readback$2, settledAtSeq }) => ({
3550
+ settlements: projection.releaseSettlements.map(({ contractId: contractId$1, operation: operation$1, callId: callId$1, outcome: outcome$1, readback: readback$2, settledAtSeq, ledgerPosition }) => ({
3200
3551
  contract_id: contractId$1,
3201
3552
  operation: operation$1,
3202
3553
  resolution_call_id: callId$1,
3203
3554
  outcome: outcome$1,
3204
3555
  readback: readback$2,
3205
- settled_at_seq: settledAtSeq
3556
+ ...ledgerPosition === void 0 ? { settled_at_seq: settledAtSeq } : { record_position: {
3557
+ channel: "private_ledger",
3558
+ position: ledgerPosition
3559
+ } }
3206
3560
  })),
3207
3561
  diagnostics: projection.releaseDiagnostics
3208
3562
  };
@@ -3269,6 +3623,518 @@ function createReleaseTool(options) {
3269
3623
  });
3270
3624
  }
3271
3625
 
3626
+ //#endregion
3627
+ //#region src/tools/observe.ts
3628
+ const execFileAsync = promisify(execFile);
3629
+ const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
3630
+ /** Read-only, post-effect file observer. The path comes from a persisted native edit call. */
3631
+ function createNativeFileObserver(host) {
3632
+ return defineTool({
3633
+ name: "context_guard_observe_file",
3634
+ description: "Read back the exact UTF-8 file after an already persisted native write or edit. This tool does not modify files or authorize the edit.",
3635
+ parameters: { effect_call_id: {
3636
+ type: "string",
3637
+ required: true
3638
+ } },
3639
+ output: {
3640
+ schema: {
3641
+ type: "object",
3642
+ additionalProperties: false,
3643
+ properties: {
3644
+ status: {
3645
+ type: "string",
3646
+ required: true,
3647
+ enum: ["observed", "unavailable"]
3648
+ },
3649
+ reason_code: {
3650
+ type: "string",
3651
+ required: true
3652
+ },
3653
+ effect_call_id: {
3654
+ type: "string",
3655
+ required: true
3656
+ },
3657
+ path: {
3658
+ type: "string",
3659
+ required: true
3660
+ },
3661
+ sha256: {
3662
+ type: "string",
3663
+ required: true
3664
+ },
3665
+ action: {
3666
+ type: "string",
3667
+ required: true,
3668
+ enum: [
3669
+ "create",
3670
+ "modify",
3671
+ "unknown"
3672
+ ]
3673
+ },
3674
+ canonical_path: { type: "string" },
3675
+ canonical_base: { type: "string" }
3676
+ }
3677
+ },
3678
+ render: (_args, value) => [{
3679
+ type: "text",
3680
+ text: JSON.stringify(value)
3681
+ }],
3682
+ presentationMeta: (_args, value) => value.status === "observed" ? { contextGuardNativeFile: {
3683
+ effectCallId: value.effect_call_id,
3684
+ path: value.path,
3685
+ sha256: value.sha256,
3686
+ action: value.action,
3687
+ ...value.canonical_path ? { canonicalPath: value.canonical_path } : {},
3688
+ ...value.canonical_base ? { canonicalBase: value.canonical_base } : {}
3689
+ } } : { contextGuardNativeFileUnavailable: { reasonCode: value.reason_code } }
3690
+ },
3691
+ async execute(args, exec) {
3692
+ const missing = (reason) => ({
3693
+ status: "unavailable",
3694
+ reason_code: reason,
3695
+ effect_call_id: args.effect_call_id,
3696
+ path: "",
3697
+ sha256: "",
3698
+ action: "unknown"
3699
+ });
3700
+ const agent = exec.agent;
3701
+ if (!agent || !host.fs || !host.flush) return missing("host_fs_unavailable");
3702
+ if (!await host.flush(agent.session)) return missing("native_effect_not_durable");
3703
+ let call;
3704
+ let result;
3705
+ let callSeq = -1;
3706
+ let resultSeq = -1;
3707
+ let duplicate = false;
3708
+ for (const raw of snapshotSessionEvents(agent.session)) {
3709
+ const event = record(raw);
3710
+ const data = record(event?.data);
3711
+ if (event?.type === "tool/call" && data?.callId === args.effect_call_id) {
3712
+ if (call) duplicate = true;
3713
+ call = data;
3714
+ callSeq = Number(event.seq);
3715
+ }
3716
+ if (event?.type === "tool/result" && record(record(data?.message)?.source)?.callId === args.effect_call_id) {
3717
+ if (result) duplicate = true;
3718
+ result = data;
3719
+ resultSeq = Number(event.seq);
3720
+ }
3721
+ }
3722
+ if (!call || !result || duplicate || callSeq >= resultSeq || call.turn !== result.turn || call.step !== result.step || ![
3723
+ "write",
3724
+ "write_file",
3725
+ "edit",
3726
+ "edit_file"
3727
+ ].includes(String(call.name))) return missing("native_effect_missing");
3728
+ const source = record(record(result.message)?.source);
3729
+ if (source?.kind !== "tool" || source.callId !== args.effect_call_id) return missing("native_effect_missing");
3730
+ const resultStatus = persistedToolResultStatus(result, args.effect_call_id);
3731
+ if (resultStatus !== "clean") return missing(resultStatus === "failure" ? "native_effect_failed" : "native_effect_untrusted");
3732
+ let effectArgs;
3733
+ try {
3734
+ effectArgs = record(JSON.parse(String(call.arguments)));
3735
+ } catch {
3736
+ return missing("native_effect_arguments_invalid");
3737
+ }
3738
+ const filePath = effectArgs?.file_path;
3739
+ if (typeof filePath !== "string" || !filePath) return missing("native_effect_target_missing");
3740
+ const action = String(call.name).startsWith("write") ? "create" : "modify";
3741
+ const cwd = record(agent.session.header)?.cwd;
3742
+ try {
3743
+ const target = await host.fs.resolve(filePath, {
3744
+ ...typeof cwd === "string" ? { cwd } : {},
3745
+ signal: exec.signal
3746
+ });
3747
+ const before = await host.fs.stat(target, exec.signal);
3748
+ if (!before || before.type !== "file" || before.size !== void 0 && before.size > 2e7) return missing("native_file_readback_unavailable");
3749
+ const content = await host.fs.readText(target, exec.signal);
3750
+ const after = await host.fs.stat(target, exec.signal);
3751
+ if (!after || after.type !== "file" || before.version !== after.version) return missing("native_file_readback_raced");
3752
+ let canonicalPath;
3753
+ let canonicalBase;
3754
+ if (typeof cwd === "string" && host.fs.processPath && host.fs.contains) {
3755
+ const base = await host.fs.resolve(cwd, { signal: exec.signal });
3756
+ const path = host.fs.processPath(target);
3757
+ const root = host.fs.processPath(base);
3758
+ const absoluteFlavor = (value) => value.startsWith("/") && !value.startsWith("//") && !value.includes("\\") && posix.normalize(value) === value ? "posix" : /^[A-Za-z]:\\/.test(value) && !value.includes("/") && !value.slice(3).includes("\\\\") && !value.slice(3).includes(":") && !value.split("\\").some((part) => part === "." || part === "..") ? "windows" : void 0;
3759
+ if (host.fs.contains(base, target) && absoluteFlavor(path) && absoluteFlavor(path) === absoluteFlavor(root)) {
3760
+ canonicalPath = path;
3761
+ canonicalBase = root;
3762
+ }
3763
+ }
3764
+ return {
3765
+ status: "observed",
3766
+ reason_code: "file_state_observed",
3767
+ effect_call_id: args.effect_call_id,
3768
+ path: target.displayPath,
3769
+ sha256: createHash("sha256").update(content, "utf8").digest("hex"),
3770
+ action,
3771
+ ...canonicalPath && canonicalBase ? {
3772
+ canonical_path: canonicalPath,
3773
+ canonical_base: canonicalBase
3774
+ } : {}
3775
+ };
3776
+ } catch {
3777
+ return missing("native_file_readback_unavailable");
3778
+ }
3779
+ }
3780
+ });
3781
+ }
3782
+ /** Fixed-argv Git readback for a persisted native shell commit/push result. */
3783
+ function createNativeGitObserver(host) {
3784
+ return defineTool({
3785
+ name: "context_guard_observe_git",
3786
+ description: "Read back a repository after a persisted native Git command; performs only fixed Git queries.",
3787
+ parameters: { effect_call_id: {
3788
+ type: "string",
3789
+ required: true
3790
+ } },
3791
+ output: {
3792
+ schema: {
3793
+ type: "object",
3794
+ additionalProperties: false,
3795
+ properties: {
3796
+ status: {
3797
+ type: "string",
3798
+ required: true,
3799
+ enum: ["observed", "unavailable"]
3800
+ },
3801
+ reason_code: {
3802
+ type: "string",
3803
+ required: true
3804
+ },
3805
+ effect_call_id: {
3806
+ type: "string",
3807
+ required: true
3808
+ },
3809
+ action: {
3810
+ type: "string",
3811
+ required: true,
3812
+ enum: [
3813
+ "commit",
3814
+ "push",
3815
+ "unknown"
3816
+ ]
3817
+ },
3818
+ repository: {
3819
+ type: "string",
3820
+ required: true
3821
+ },
3822
+ branch: {
3823
+ type: "string",
3824
+ required: true
3825
+ },
3826
+ remote: {
3827
+ type: "string",
3828
+ required: true
3829
+ },
3830
+ refspec: {
3831
+ type: "string",
3832
+ required: true
3833
+ },
3834
+ post_oid: {
3835
+ type: "string",
3836
+ required: true
3837
+ },
3838
+ parent_oid: {
3839
+ type: "string",
3840
+ required: true
3841
+ },
3842
+ tree_oid: {
3843
+ type: "string",
3844
+ required: true
3845
+ }
3846
+ }
3847
+ },
3848
+ render: (_args, value) => [{
3849
+ type: "text",
3850
+ text: JSON.stringify(value)
3851
+ }],
3852
+ presentationMeta: (_args, value) => value.status === "observed" ? { contextGuardNativeGit: {
3853
+ effectCallId: value.effect_call_id,
3854
+ action: value.action,
3855
+ repository: value.repository,
3856
+ branch: value.branch,
3857
+ remote: value.remote,
3858
+ refspec: value.refspec,
3859
+ postOid: value.post_oid,
3860
+ parentOid: value.parent_oid,
3861
+ treeOid: value.tree_oid
3862
+ } } : { contextGuardNativeGitUnavailable: { reasonCode: value.reason_code } }
3863
+ },
3864
+ async execute(args, exec) {
3865
+ const missing = (reason) => ({
3866
+ status: "unavailable",
3867
+ reason_code: reason,
3868
+ effect_call_id: args.effect_call_id,
3869
+ action: "unknown",
3870
+ repository: "",
3871
+ branch: "",
3872
+ remote: "",
3873
+ refspec: "",
3874
+ post_oid: "",
3875
+ parent_oid: "",
3876
+ tree_oid: ""
3877
+ });
3878
+ const session = exec.agent?.session;
3879
+ if (!session || !host.flush || !await host.flush(session)) return missing("native_effect_not_durable");
3880
+ let call;
3881
+ let result;
3882
+ let callSeq = -1;
3883
+ let resultSeq = -1;
3884
+ let duplicate = false;
3885
+ for (const raw of snapshotSessionEvents(session)) {
3886
+ const event = record(raw);
3887
+ const data = record(event?.data);
3888
+ if (event?.type === "tool/call" && data?.callId === args.effect_call_id) {
3889
+ if (call) duplicate = true;
3890
+ call = data;
3891
+ callSeq = Number(event.seq);
3892
+ }
3893
+ if (event?.type === "tool/result" && record(record(data?.message)?.source)?.callId === args.effect_call_id) {
3894
+ if (result) duplicate = true;
3895
+ result = data;
3896
+ resultSeq = Number(event.seq);
3897
+ }
3898
+ }
3899
+ if (!call || !result || duplicate || callSeq >= resultSeq || call.turn !== result.turn || call.step !== result.step || call.name !== "bash" && call.name !== "pwsh") return missing("native_effect_missing");
3900
+ const message = record(result.message);
3901
+ const source = record(message?.source);
3902
+ if (source?.kind !== "tool" || source.callId !== args.effect_call_id) return missing("native_effect_missing");
3903
+ const resultStatus = persistedToolResultStatus(result, args.effect_call_id);
3904
+ if (resultStatus !== "clean") return missing(resultStatus === "failure" ? "native_effect_failed" : "native_effect_untrusted");
3905
+ let effectArgs;
3906
+ try {
3907
+ effectArgs = record(JSON.parse(String(call.arguments)));
3908
+ } catch {
3909
+ return missing("native_effect_arguments_invalid");
3910
+ }
3911
+ const command = effectArgs?.command;
3912
+ const repository = effectArgs?.workdir;
3913
+ if (typeof command !== "string" || typeof repository !== "string" || !repository) return missing("native_git_target_missing");
3914
+ const parsed = canonicalArgvFromCommand(command, call.name);
3915
+ const argv = parsed.argv;
3916
+ if (parsed.status !== "supported" || argv[0] !== "git") return missing("native_git_command_unsupported");
3917
+ const action = argv[1];
3918
+ if (action !== "commit" && action !== "push") return missing("native_git_command_unsupported");
3919
+ const gitAction = action;
3920
+ const output = Array.isArray(message?.content) ? extractTextContent(message.content) : "";
3921
+ const git$1 = async (...query) => (await execFileAsync("git", [
3922
+ "-C",
3923
+ repository,
3924
+ ...query
3925
+ ], {
3926
+ encoding: "utf8",
3927
+ timeout: 5e3,
3928
+ maxBuffer: 1024 * 1024
3929
+ })).stdout.trim();
3930
+ try {
3931
+ const top = await git$1("rev-parse", "--show-toplevel");
3932
+ if (!top || await realpath(top) !== await realpath(repository)) return missing("native_git_repository_mismatch");
3933
+ const observedRepository = repository;
3934
+ const branch = await git$1("symbolic-ref", "--short", "HEAD");
3935
+ const postOid = await git$1("rev-parse", "HEAD");
3936
+ if (!/^[0-9a-f]{40,64}$/.test(postOid)) return missing("native_git_readback_unavailable");
3937
+ if (action === "commit") {
3938
+ if (argv.length !== 4 || argv[2] !== "-m" || !argv[3] || !(/* @__PURE__ */ new RegExp(`\\b${postOid.slice(0, 7)}[0-9a-f]*\\b`)).test(output)) return missing("native_git_effect_output_unbound");
3939
+ const parentOid = await git$1("rev-parse", "HEAD^");
3940
+ const treeOid = await git$1("rev-parse", "HEAD^{tree}");
3941
+ return {
3942
+ status: "observed",
3943
+ reason_code: "git_commit_observed",
3944
+ effect_call_id: args.effect_call_id,
3945
+ action: gitAction,
3946
+ repository: observedRepository,
3947
+ branch,
3948
+ remote: "",
3949
+ refspec: "",
3950
+ post_oid: postOid,
3951
+ parent_oid: parentOid,
3952
+ tree_oid: treeOid
3953
+ };
3954
+ }
3955
+ const remote = argv[2];
3956
+ const refspec = argv[3];
3957
+ if (argv.length !== 4 || !remote || !/^refs\/heads\/[^:]+:refs\/heads\/[^:]+$/.test(refspec)) return missing("native_git_refspec_unsupported");
3958
+ const [src, dst] = refspec.split(":");
3959
+ const localOid = await git$1("rev-parse", src);
3960
+ const remoteOid = (await git$1("ls-remote", "--exit-code", remote, dst)).split(/\s+/)[0];
3961
+ const destinationName = dst.slice(11);
3962
+ const reportedUpdate = output.includes(localOid.slice(0, 7)) || output.includes("[new branch]") && output.includes(`-> ${destinationName}`);
3963
+ if (remoteOid !== localOid || !reportedUpdate) return missing("native_git_push_readback_mismatch");
3964
+ return {
3965
+ status: "observed",
3966
+ reason_code: "git_push_observed",
3967
+ effect_call_id: args.effect_call_id,
3968
+ action: gitAction,
3969
+ repository: observedRepository,
3970
+ branch,
3971
+ remote,
3972
+ refspec,
3973
+ post_oid: remoteOid,
3974
+ parent_oid: "",
3975
+ tree_oid: ""
3976
+ };
3977
+ } catch {
3978
+ return missing("native_git_readback_unavailable");
3979
+ }
3980
+ }
3981
+ });
3982
+ }
3983
+ /** Specific package-script readiness, with a stable changed input for an
3984
+ * assessment. The observer never executes the script or infers success. */
3985
+ function createTestReadinessObserver(host) {
3986
+ return defineTool({
3987
+ name: "context_guard_observe_test_readiness",
3988
+ description: "Read a pending test or assessment script and its concrete inputs; never runs the script.",
3989
+ parameters: { item_id: {
3990
+ type: "string",
3991
+ required: true
3992
+ } },
3993
+ output: {
3994
+ schema: {
3995
+ type: "object",
3996
+ additionalProperties: false,
3997
+ properties: {
3998
+ status: {
3999
+ type: "string",
4000
+ required: true,
4001
+ enum: ["ready", "unavailable"]
4002
+ },
4003
+ reason_code: {
4004
+ type: "string",
4005
+ required: true
4006
+ },
4007
+ item_id: {
4008
+ type: "string",
4009
+ required: true
4010
+ },
4011
+ scope: {
4012
+ type: "string",
4013
+ required: true
4014
+ },
4015
+ manifest_sha256: {
4016
+ type: "string",
4017
+ required: true
4018
+ },
4019
+ predicate: {
4020
+ type: "string",
4021
+ required: true
4022
+ },
4023
+ script_name: {
4024
+ type: "string",
4025
+ required: true
4026
+ },
4027
+ selected_path: {
4028
+ type: "string",
4029
+ required: true
4030
+ },
4031
+ effect_call_id: {
4032
+ type: "string",
4033
+ required: true
4034
+ },
4035
+ input_sha256: {
4036
+ type: "string",
4037
+ required: true
4038
+ }
4039
+ }
4040
+ },
4041
+ render: (_args, value) => [{
4042
+ type: "text",
4043
+ text: JSON.stringify(value)
4044
+ }],
4045
+ presentationMeta: (_args, value) => value.status === "ready" ? { contextGuardTestReadiness: {
4046
+ itemId: value.item_id,
4047
+ scope: value.scope,
4048
+ manifestSha256: value.manifest_sha256,
4049
+ predicate: value.predicate,
4050
+ scriptName: value.script_name,
4051
+ selectedPath: value.selected_path,
4052
+ effectCallId: value.effect_call_id,
4053
+ inputSha256: value.input_sha256
4054
+ } } : { contextGuardTestReadinessUnavailable: { reasonCode: value.reason_code } }
4055
+ },
4056
+ async execute(args, exec) {
4057
+ const missing = (reason) => ({
4058
+ status: "unavailable",
4059
+ reason_code: reason,
4060
+ item_id: args.item_id,
4061
+ scope: "",
4062
+ manifest_sha256: "",
4063
+ predicate: "",
4064
+ script_name: "",
4065
+ selected_path: "",
4066
+ effect_call_id: "",
4067
+ input_sha256: ""
4068
+ });
4069
+ if (!exec.agent?.session || !host.flush || !host.fs || !await host.flush(exec.agent.session)) return missing("readiness_host_unavailable");
4070
+ const projection = host.getProjection();
4071
+ const item = projection?.items.get(args.item_id);
4072
+ if (!item || item.status !== "pending" || !["test", "verify"].includes(item.semanticAction ?? "") || item.authority !== "root_instruction" || item.authorityDisposition !== "executable_now" || item.legacyFlags?.length || item.waitAuthorization || item.condition || typeof item.requestedTarget?.scope !== "string") return missing("readiness_item_unsupported");
4073
+ const scope = item.requestedTarget.scope;
4074
+ const assessment = item.semanticAction === "verify";
4075
+ if (typeof item.requestedTarget.script_name === "string") return missing("readiness_script_capability_unavailable");
4076
+ const scriptName = assessment && /(?:吞吐|性能|时延|延迟|throughput|performance|latency)/iu.test(item.normalizedText) ? "benchmark" : "test";
4077
+ let selectedPath = "", effectCallId = "", inputSha256 = "";
4078
+ if (assessment) {
4079
+ const unitStart = item.unitId ? projection?.units.get(item.unitId)?.openedAtSeq : void 0;
4080
+ if (unitStart === void 0) return missing("assessment_unit_unavailable");
4081
+ const changes = [...projection?.evidence.values() ?? []].filter((fact) => fact.epoch === projection?.epoch && fact.toolResultSeq >= unitStart && fact.outcome === "success" && fact.parseStatus === "supported" && fact.semanticAction === "modify" && fact.evidenceRole === "effect").flatMap((fact) => (fact.operations ?? []).filter((op) => op.op === "modify" && typeof op.path === "string").map((op) => ({
4082
+ path: op.path,
4083
+ callId: fact.callId
4084
+ })));
4085
+ const paths = [...new Set(changes.map((change) => change.path))];
4086
+ if (paths.length > 1) return missing("assessment_input_ambiguous");
4087
+ if (paths.length === 1) {
4088
+ const change = changes.find((entry) => entry.path === paths[0]);
4089
+ selectedPath = change.path;
4090
+ effectCallId = change.callId;
4091
+ try {
4092
+ const changed = await host.fs.resolve(selectedPath, { signal: exec.signal });
4093
+ const before = await host.fs.stat(changed, exec.signal);
4094
+ if (!before || before.type !== "file" || before.size !== void 0 && before.size > 2e7) return missing("assessment_input_unavailable");
4095
+ const raw = await host.fs.readText(changed, exec.signal);
4096
+ const after = await host.fs.stat(changed, exec.signal);
4097
+ if (!after || after.type !== "file" || before.version !== after.version) return missing("assessment_input_raced");
4098
+ inputSha256 = createHash("sha256").update(raw, "utf8").digest("hex");
4099
+ } catch {
4100
+ return missing("assessment_input_unavailable");
4101
+ }
4102
+ }
4103
+ }
4104
+ try {
4105
+ if (/^[A-Za-z]:/.test(scope) && (!/^[A-Za-z]:\\/.test(scope) || scope.includes("/"))) return missing("readiness_scope_unavailable");
4106
+ const manifestPath = /^[A-Za-z]:\\/.test(scope) ? win32.join(scope, "package.json") : posix.join(scope, "package.json");
4107
+ const target = await host.fs.resolve(manifestPath, { signal: exec.signal });
4108
+ const before = await host.fs.stat(target, exec.signal);
4109
+ if (!before || before.type !== "file" || before.size !== void 0 && before.size > 2e6) return missing("readiness_manifest_unavailable");
4110
+ const raw = await host.fs.readText(target, exec.signal);
4111
+ const after = await host.fs.stat(target, exec.signal);
4112
+ if (!after || after.type !== "file" || before.version !== after.version) return missing("readiness_manifest_raced");
4113
+ const manifest = record(JSON.parse(raw));
4114
+ if (typeof record(manifest?.scripts)?.[scriptName] !== "string" || !String(record(manifest?.scripts)?.[scriptName]).trim()) return missing("readiness_script_missing");
4115
+ if (assessment && !selectedPath) {
4116
+ selectedPath = target.displayPath;
4117
+ inputSha256 = createHash("sha256").update(raw, "utf8").digest("hex");
4118
+ }
4119
+ return {
4120
+ status: "ready",
4121
+ reason_code: assessment ? "assessment_inputs_ready" : "package_test_script_ready",
4122
+ item_id: args.item_id,
4123
+ scope,
4124
+ manifest_sha256: createHash("sha256").update(raw, "utf8").digest("hex"),
4125
+ predicate: assessment ? "verification_passed" : "test_passed",
4126
+ script_name: scriptName,
4127
+ selected_path: selectedPath,
4128
+ effect_call_id: effectCallId,
4129
+ input_sha256: inputSha256
4130
+ };
4131
+ } catch {
4132
+ return missing("readiness_manifest_unavailable");
4133
+ }
4134
+ }
4135
+ });
4136
+ }
4137
+
3272
4138
  //#endregion
3273
4139
  //#region src/tools/external-operation.ts
3274
4140
  function createExternalOperationTool(read, capability) {
@@ -3360,14 +4226,17 @@ const PRESERVED_DIGEST_DOMAINS = [
3360
4226
  "ccg.proofManifest.v1"
3361
4227
  ];
3362
4228
  function migrationReport(projection) {
3363
- const v5 = projection.boundaryProtocol === 5;
4229
+ const v6 = projection.boundaryProtocol === 6;
4230
+ const v5 = projection.boundaryProtocol !== void 0 && projection.boundaryProtocol >= 5;
3364
4231
  const legacyItemIds = certifiableOpenItems(projection).filter((item) => item.unitId === void 0).map((item) => item.id);
3365
4232
  const closure = v5 ? certificateClosure(projection) : { itemIds: [] };
3366
4233
  const reasonCodes = [];
3367
4234
  if (!v5) reasonCodes.push("legacy_session_keeps_v4_contract");
3368
4235
  if (v5 && legacyItemIds.length > 0) reasonCodes.push("pre_v5_obligations_retained_in_closure");
4236
+ if (v6) reasonCodes.push("v6_ordinary_host_facts_and_legacy_review");
4237
+ if (v6 && projection.coreV2Reason) reasonCodes.push(`core_v2_${projection.coreV2Reason}`);
3369
4238
  return {
3370
- ruleMode: v5 ? "v5" : "legacy-v4",
4239
+ ruleMode: v6 ? "v6" : v5 ? "v5" : "legacy-v4",
3371
4240
  certificateVersion: v5 ? CERTIFICATE_VERSION_V2 : CERTIFICATE_VERSION,
3372
4241
  stopProtocolVersion: v5 ? STOP_PROTOCOL_VERSION_V2 : STOP_PROTOCOL_VERSION,
3373
4242
  unitClosure: v5,
@@ -3377,7 +4246,7 @@ function migrationReport(projection) {
3377
4246
  preservedDigestDomains: [...PRESERVED_DIGEST_DOMAINS],
3378
4247
  historyOnlyCertificateVersions: v5 ? [CERTIFICATE_VERSION] : [],
3379
4248
  rollbackRequiresStateSnapshot: v5,
3380
- rollbackInstruction: v5 ? "Restore the 0.5.x state snapshot before starting the older binary. Replaying a v5 log with 0.5.x fails closed with certificate_replay_mismatch; never migrate new-schema data down by hand." : "No rollback action is required for this session: it has not written a v5 boundary.",
4249
+ rollbackInstruction: v6 ? "Restore a pre-v6 state snapshot before running 0.6.x. The v6 boundary, native-observation digest and migration review must not be read as v5 current authority or downgraded by hand." : v5 ? "Restore the 0.5.x state snapshot before starting the older binary. Replaying a v5 log with 0.5.x fails closed with certificate_replay_mismatch; never migrate new-schema data down by hand." : "No rollback action is required for this session: it has not written a v5 boundary.",
3381
4250
  reasonCodes
3382
4251
  };
3383
4252
  }
@@ -3471,17 +4340,23 @@ function releaseResponse(projection, rawInput) {
3471
4340
  operations: releaseCoverage(contract),
3472
4341
  expires_at_epoch_ms: contract.expiresAtEpochMs ?? null,
3473
4342
  consumed_operations: projection.releaseSettlements.filter((settlement) => settlement.contractId === contract.contractId && settlement.outcome === "settled").map((settlement) => settlement.operation),
3474
- in_flight: projection.releaseReservations.filter((reservation) => reservation.contractId === contract.contractId && !projection.releaseSettlements.some((settlement) => settlement.callId === reservation.callId && (settlement.outcome === "settled" || settlement.outcome === "not_effected"))).map(({ operation, callId, startedAtSeq }) => ({
4343
+ in_flight: projection.releaseReservations.filter((reservation) => reservation.contractId === contract.contractId && !projection.releaseSettlements.some((settlement) => settlement.callId === reservation.callId && (settlement.outcome === "settled" || settlement.outcome === "not_effected"))).map(({ operation, callId, startedAtSeq, ledgerPosition }) => ({
3475
4344
  operation,
3476
4345
  call_id: callId,
3477
- started_at_seq: startedAtSeq
4346
+ ...ledgerPosition === void 0 ? { started_at_seq: startedAtSeq } : { record_position: {
4347
+ channel: "private_ledger",
4348
+ position: ledgerPosition
4349
+ } }
3478
4350
  })),
3479
- settlements: projection.releaseSettlements.filter((settlement) => settlement.contractId === contract.contractId).map(({ operation, callId, outcome, readback: readback$1, settledAtSeq }) => ({
4351
+ settlements: projection.releaseSettlements.filter((settlement) => settlement.contractId === contract.contractId).map(({ operation, callId, outcome, readback: readback$1, settledAtSeq, ledgerPosition }) => ({
3480
4352
  operation,
3481
4353
  call_id: callId,
3482
4354
  outcome,
3483
4355
  readback: readback$1,
3484
- settled_at_seq: settledAtSeq
4356
+ ...ledgerPosition === void 0 ? { settled_at_seq: settledAtSeq } : { record_position: {
4357
+ channel: "private_ledger",
4358
+ position: ledgerPosition
4359
+ } }
3485
4360
  }))
3486
4361
  }));
3487
4362
  return {
@@ -4463,10 +5338,385 @@ function resolveConfig(config) {
4463
5338
  };
4464
5339
  }
4465
5340
 
5341
+ //#endregion
5342
+ //#region src/domain/private-ledger.ts
5343
+ const normalizeContext = (value) => typeof value === "string" ? {
5344
+ sessionId: value,
5345
+ sessionHeader: { id: value },
5346
+ cwd: "/",
5347
+ hostLockDigest: "test-seam"
5348
+ } : value;
5349
+ const canonical = (value) => {
5350
+ if (value === null || typeof value === "boolean" || typeof value === "string") return JSON.stringify(value);
5351
+ if (typeof value === "number") {
5352
+ if (!Number.isFinite(value) || Object.is(value, -0)) throw new TypeError("private_ledger_non_json_number");
5353
+ return JSON.stringify(value);
5354
+ }
5355
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
5356
+ if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`).join(",")}}`;
5357
+ throw new TypeError("private_ledger_non_json_value");
5358
+ };
5359
+ const digestRecord = (record$2) => sha256(canonical(record$2));
5360
+ const sessionDigest = (sessionId) => sha256(`dsh-completion-guard/private-ledger/v1\0${sessionId}`);
5361
+ const contextDigest = (context, root) => sha256(canonical({
5362
+ session_sha256: sessionDigest(context.sessionId),
5363
+ session_header: context.sessionHeader,
5364
+ cwd_sha256: sha256(context.cwd),
5365
+ host_lock_sha256: context.hostLockDigest,
5366
+ ledger_root_sha256: sha256(realpathSync(root))
5367
+ }));
5368
+ const ledgerPath = (root, context) => join(root, `${sessionDigest(context.sessionId)}.jsonl`);
5369
+ const anchorPath = (root) => join(root, "session-anchors.v1.jsonl");
5370
+ const rootLockPath = (root) => join(root, ".writer.lock");
5371
+ const privateLedgerContractDigest = (contract) => {
5372
+ if (!contract || typeof contract !== "object" || Array.isArray(contract)) return sha256(canonical(contract));
5373
+ const { revokedAtSeq: _mutableRevocation,...immutable } = contract;
5374
+ return sha256(canonical(immutable));
5375
+ };
5376
+ const privateLedgerTargetDigest = (target) => sha256(canonical(target));
5377
+ /** Mirrors the audited dsh-home-paths precedence without importing another host package. */
5378
+ function resolvePrivateLedgerRoot(configured, envHome, osHome) {
5379
+ const selected = configured ?? (envHome?.trim() ? envHome : join(osHome, ".dsh"));
5380
+ if (!selected || !osHome) return void 0;
5381
+ return join(resolve(selected === "~" ? osHome : selected.startsWith("~/") || selected.startsWith("~\\") ? join(osHome, selected.slice(2)) : selected), "completion-guard", "private-ledger-v1");
5382
+ }
5383
+ function ensureRoot(root) {
5384
+ if (resolve(root) !== root) throw new Error("private_ledger_root_not_normalized");
5385
+ mkdirSync(root, {
5386
+ recursive: true,
5387
+ mode: 448
5388
+ });
5389
+ const stat = lstatSync(root);
5390
+ if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("private_ledger_root_unsafe");
5391
+ }
5392
+ function openRegular(path, flags, mode = 384) {
5393
+ const fd = openSync(path, flags | (process.platform === "win32" ? 0 : constants.O_NOFOLLOW), mode);
5394
+ const stat = fstatSync(fd);
5395
+ if (!stat.isFile()) {
5396
+ closeSync(fd);
5397
+ throw new Error("private_ledger_file_unsafe");
5398
+ }
5399
+ if (process.platform !== "win32" && (stat.mode & 63) !== 0) fchmodSync(fd, 384);
5400
+ return fd;
5401
+ }
5402
+ function writeAll(fd, text) {
5403
+ const bytes = Buffer.from(text);
5404
+ let offset = 0;
5405
+ while (offset < bytes.length) {
5406
+ const written = writeSync(fd, bytes, offset, bytes.length - offset);
5407
+ if (written <= 0) throw new Error("private_ledger_partial_write");
5408
+ offset += written;
5409
+ }
5410
+ }
5411
+ function syncDirectory(root) {
5412
+ if (process.platform === "win32") return;
5413
+ const fd = openSync(root, constants.O_RDONLY);
5414
+ try {
5415
+ fsyncSync(fd);
5416
+ } finally {
5417
+ closeSync(fd);
5418
+ }
5419
+ }
5420
+ function readAnchors(root) {
5421
+ const path = anchorPath(root);
5422
+ if (!existsSync(path)) return /* @__PURE__ */ new Map();
5423
+ const fd = openRegular(path, constants.O_RDONLY);
5424
+ let raw;
5425
+ try {
5426
+ raw = readFileSync(fd, "utf8");
5427
+ } finally {
5428
+ closeSync(fd);
5429
+ }
5430
+ if (raw && !raw.endsWith("\n")) throw new Error("private_ledger_anchor_truncated");
5431
+ const anchors = /* @__PURE__ */ new Map();
5432
+ for (const line of raw.split("\n").filter(Boolean)) {
5433
+ const value = JSON.parse(line);
5434
+ const unsigned = {
5435
+ version: 1,
5436
+ session_sha256: value.session_sha256,
5437
+ context_sha256: value.context_sha256
5438
+ };
5439
+ if (value.version !== 1 || typeof value.session_sha256 !== "string" || typeof value.context_sha256 !== "string" || value.anchor_sha256 !== sha256(canonical(unsigned))) throw new Error("private_ledger_anchor_invalid");
5440
+ const existing = anchors.get(value.session_sha256);
5441
+ if (existing && existing !== value.context_sha256) throw new Error("private_ledger_anchor_conflict");
5442
+ anchors.set(value.session_sha256, value.context_sha256);
5443
+ }
5444
+ return anchors;
5445
+ }
5446
+ function readPrivateLedger(root, input) {
5447
+ if (!root) return {
5448
+ records: [],
5449
+ damaged: true,
5450
+ anchored: false
5451
+ };
5452
+ try {
5453
+ const context = normalizeContext(input);
5454
+ if (!existsSync(root)) return {
5455
+ records: [],
5456
+ damaged: false,
5457
+ anchored: false
5458
+ };
5459
+ const rootStat = lstatSync(root);
5460
+ if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) return {
5461
+ records: [],
5462
+ damaged: true,
5463
+ anchored: false
5464
+ };
5465
+ const session = sessionDigest(context.sessionId);
5466
+ const expectedContext = contextDigest(context, root);
5467
+ const anchored = readAnchors(root).get(session);
5468
+ if (anchored !== void 0 && anchored !== expectedContext) return {
5469
+ records: [],
5470
+ damaged: true,
5471
+ anchored: true
5472
+ };
5473
+ const path = ledgerPath(root, context);
5474
+ if (!existsSync(path)) return {
5475
+ records: [],
5476
+ damaged: anchored !== void 0,
5477
+ anchored: anchored !== void 0
5478
+ };
5479
+ if (anchored === void 0) return {
5480
+ records: [],
5481
+ damaged: true,
5482
+ anchored: false
5483
+ };
5484
+ const fd = openRegular(path, constants.O_RDONLY);
5485
+ let raw;
5486
+ try {
5487
+ raw = readFileSync(fd, "utf8");
5488
+ } finally {
5489
+ closeSync(fd);
5490
+ }
5491
+ if (raw && !raw.endsWith("\n")) return {
5492
+ records: [],
5493
+ damaged: true,
5494
+ anchored: true
5495
+ };
5496
+ const records = [];
5497
+ let prior = null;
5498
+ for (const [index, line] of raw.split("\n").filter(Boolean).entries()) {
5499
+ const value = JSON.parse(line);
5500
+ const { record_sha256,...unsigned } = value;
5501
+ if (value.version !== 1 || value.session_sha256 !== session || value.context_sha256 !== expectedContext || value.position !== index + 1 || value.prior_sha256 !== prior || ![
5502
+ "release_reservation",
5503
+ "release_settlement",
5504
+ "restart_intent"
5505
+ ].includes(value.kind) || !value.payload || typeof value.payload !== "object" || Array.isArray(value.payload) || record_sha256 !== digestRecord(unsigned)) return {
5506
+ records: [],
5507
+ damaged: true,
5508
+ anchored: true
5509
+ };
5510
+ records.push(value);
5511
+ prior = record_sha256;
5512
+ }
5513
+ return {
5514
+ records,
5515
+ damaged: false,
5516
+ anchored: true
5517
+ };
5518
+ } catch {
5519
+ return {
5520
+ records: [],
5521
+ damaged: true,
5522
+ anchored: false
5523
+ };
5524
+ }
5525
+ }
5526
+ /** Establish the provider-invisible anchor when a live runtime observes a new adoption. */
5527
+ function initializePrivateLedger(root, input) {
5528
+ if (!root) return false;
5529
+ let lockFd;
5530
+ try {
5531
+ const context = normalizeContext(input);
5532
+ ensureRoot(root);
5533
+ lockFd = openRegular(rootLockPath(root), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);
5534
+ const session = sessionDigest(context.sessionId);
5535
+ const expectedContext = contextDigest(context, root);
5536
+ const anchored = readAnchors(root).get(session);
5537
+ if (anchored !== void 0) return anchored === expectedContext;
5538
+ const unsignedAnchor = {
5539
+ version: 1,
5540
+ session_sha256: session,
5541
+ context_sha256: expectedContext
5542
+ };
5543
+ const fd = openRegular(anchorPath(root), constants.O_WRONLY | constants.O_CREAT | constants.O_APPEND);
5544
+ try {
5545
+ writeAll(fd, `${canonical({
5546
+ ...unsignedAnchor,
5547
+ anchor_sha256: sha256(canonical(unsignedAnchor))
5548
+ })}\n`);
5549
+ fsyncSync(fd);
5550
+ } finally {
5551
+ closeSync(fd);
5552
+ }
5553
+ const ledgerFd = openRegular(ledgerPath(root, context), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);
5554
+ try {
5555
+ fsyncSync(ledgerFd);
5556
+ } finally {
5557
+ closeSync(ledgerFd);
5558
+ }
5559
+ syncDirectory(root);
5560
+ return true;
5561
+ } catch {
5562
+ return false;
5563
+ } finally {
5564
+ if (lockFd !== void 0) {
5565
+ try {
5566
+ closeSync(lockFd);
5567
+ } catch {}
5568
+ try {
5569
+ unlinkSync(rootLockPath(root));
5570
+ } catch {}
5571
+ }
5572
+ }
5573
+ }
5574
+ function appendPrivateLedger(root, input, kind, payload) {
5575
+ if (!root) return false;
5576
+ let lockFd;
5577
+ try {
5578
+ const context = normalizeContext(input);
5579
+ ensureRoot(root);
5580
+ lockFd = openRegular(rootLockPath(root), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);
5581
+ const session = sessionDigest(context.sessionId);
5582
+ const expectedContext = contextDigest(context, root);
5583
+ const anchored = readAnchors(root).get(session);
5584
+ if (anchored !== void 0 && anchored !== expectedContext) return false;
5585
+ const snapshot = anchored === void 0 ? {
5586
+ records: [],
5587
+ damaged: false
5588
+ } : readPrivateLedger(root, context);
5589
+ if (snapshot.damaged) return false;
5590
+ if (anchored === void 0) {
5591
+ const unsignedAnchor = {
5592
+ version: 1,
5593
+ session_sha256: session,
5594
+ context_sha256: expectedContext
5595
+ };
5596
+ const fd$1 = openRegular(anchorPath(root), constants.O_WRONLY | constants.O_CREAT | constants.O_APPEND);
5597
+ try {
5598
+ writeAll(fd$1, `${canonical({
5599
+ ...unsignedAnchor,
5600
+ anchor_sha256: sha256(canonical(unsignedAnchor))
5601
+ })}\n`);
5602
+ fsyncSync(fd$1);
5603
+ } finally {
5604
+ closeSync(fd$1);
5605
+ }
5606
+ syncDirectory(root);
5607
+ }
5608
+ if (kind === "release_settlement") {
5609
+ const settlement = normalizeSettlement(payload);
5610
+ const reservation = settlement && [...snapshot.records].reverse().find((record$3) => record$3.kind === "release_reservation" && record$3.payload.contractId === settlement.contractId && record$3.payload.operation === settlement.operation && record$3.payload.callId === settlement.callId);
5611
+ if (!reservation) return false;
5612
+ payload = {
5613
+ ...payload,
5614
+ reservation_sha256: reservation.record_sha256,
5615
+ contract_sha256: reservation.payload.contract_sha256,
5616
+ target_sha256: reservation.payload.target_sha256
5617
+ };
5618
+ }
5619
+ const unsigned = {
5620
+ version: 1,
5621
+ session_sha256: session,
5622
+ context_sha256: expectedContext,
5623
+ position: snapshot.records.length + 1,
5624
+ prior_sha256: snapshot.records.at(-1)?.record_sha256 ?? null,
5625
+ kind,
5626
+ payload
5627
+ };
5628
+ const record$2 = {
5629
+ ...unsigned,
5630
+ record_sha256: digestRecord(unsigned)
5631
+ };
5632
+ const fd = openRegular(ledgerPath(root, context), constants.O_WRONLY | constants.O_CREAT | constants.O_APPEND);
5633
+ try {
5634
+ writeAll(fd, `${canonical(record$2)}\n`);
5635
+ fsyncSync(fd);
5636
+ } finally {
5637
+ closeSync(fd);
5638
+ }
5639
+ syncDirectory(root);
5640
+ return true;
5641
+ } catch {
5642
+ return false;
5643
+ } finally {
5644
+ if (lockFd !== void 0) {
5645
+ try {
5646
+ closeSync(lockFd);
5647
+ } catch {}
5648
+ try {
5649
+ unlinkSync(rootLockPath(root));
5650
+ } catch {}
5651
+ }
5652
+ }
5653
+ }
5654
+ function applyPrivateLedger(projection, snapshot) {
5655
+ if (snapshot.damaged || projection.releaseContracts.length > 0 && snapshot.anchored === false) {
5656
+ projection.releaseStateDamaged = true;
5657
+ if (!projection.releaseDiagnostics.some((row) => row.reasonCode === "private_ledger_damaged")) projection.releaseDiagnostics.push({
5658
+ seq: 0,
5659
+ reasonCode: "private_ledger_damaged"
5660
+ });
5661
+ return;
5662
+ }
5663
+ const reservations = /* @__PURE__ */ new Map();
5664
+ for (const record$2 of snapshot.records) if (record$2.kind === "release_reservation") {
5665
+ const normalized = normalizeReservation(record$2.payload);
5666
+ const contract = normalized && projection.releaseContracts.find((entry) => entry.contractId === normalized.contractId);
5667
+ if (!normalized || !contract || record$2.payload.contract_sha256 !== privateLedgerContractDigest(contract) || typeof record$2.payload.target_sha256 !== "string") {
5668
+ projection.releaseStateDamaged = true;
5669
+ continue;
5670
+ }
5671
+ const key = `${normalized.contractId}\0${normalized.operation}\0${normalized.callId}`;
5672
+ if (reservations.has(key)) {
5673
+ projection.releaseStateDamaged = true;
5674
+ continue;
5675
+ }
5676
+ reservations.set(key, record$2);
5677
+ const existing = projection.releaseReservations.find((entry) => entry.callId === normalized.callId);
5678
+ if (existing && (existing.contractId !== normalized.contractId || existing.operation !== normalized.operation)) {
5679
+ projection.releaseStateDamaged = true;
5680
+ continue;
5681
+ }
5682
+ if (!existing) projection.releaseReservations.push({
5683
+ ...normalized,
5684
+ startedAtSeq: 0,
5685
+ ledgerPosition: record$2.position
5686
+ });
5687
+ } else if (record$2.kind === "release_settlement") {
5688
+ const normalized = normalizeSettlement(record$2.payload);
5689
+ const key = normalized && `${normalized.contractId}\0${normalized.operation}\0${normalized.callId}`;
5690
+ const reservationRecord = key ? reservations.get(key) : void 0;
5691
+ const contract = normalized && projection.releaseContracts.find((entry) => entry.contractId === normalized.contractId);
5692
+ const source = record$2.payload.settlement_source;
5693
+ const readbackVerdict = normalized && contract ? readbackSettlesContract(contract, normalized.readback, reservationRecord ? normalizeReservation(reservationRecord.payload)?.observedArtifactSri : void 0) : void 0;
5694
+ if (!normalized || !reservationRecord || !contract || source !== "effect" && source !== "reconcile" || normalized.outcome === "not_effected" && source !== "effect" || source === "reconcile" && normalized.readback === "unavailable" || record$2.payload.reservation_sha256 !== reservationRecord.record_sha256 || record$2.payload.contract_sha256 !== reservationRecord.payload.contract_sha256 || record$2.payload.target_sha256 !== reservationRecord.payload.target_sha256 || normalized.outcome === "settled" && readbackVerdict !== "settled" || source === "reconcile" && readbackVerdict === "mismatch") {
5695
+ projection.releaseStateDamaged = true;
5696
+ continue;
5697
+ }
5698
+ const pinned = {
5699
+ ...normalized,
5700
+ settledAtSeq: 0,
5701
+ ledgerPosition: record$2.position
5702
+ };
5703
+ const index = projection.releaseSettlements.findIndex((entry) => entry.contractId === pinned.contractId && entry.operation === pinned.operation && entry.callId === pinned.callId);
5704
+ if (index < 0) projection.releaseSettlements.push(pinned);
5705
+ else if (OUTCOME_STRENGTH[pinned.outcome] >= OUTCOME_STRENGTH[projection.releaseSettlements[index].outcome]) projection.releaseSettlements[index] = pinned;
5706
+ }
5707
+ }
5708
+ function hasPrivateRestartIntent(snapshot, resolutionCallId, serviceId, preGeneration) {
5709
+ return !snapshot.damaged && snapshot.records.some((record$2) => record$2.kind === "restart_intent" && record$2.payload.resolution_call_id === resolutionCallId && record$2.payload.service_id === serviceId && record$2.payload.pre_generation === preGeneration);
5710
+ }
5711
+
4466
5712
  //#endregion
4467
5713
  //#region src/runtime.ts
4468
5714
  const name = "context-guard";
4469
- const inject = ["sessions", "commands"];
5715
+ const inject = [
5716
+ "sessions",
5717
+ "commands",
5718
+ "fs"
5719
+ ];
4470
5720
  /**
4471
5721
  * Bind an explicit mutation to one live root-owned contract item. Resolution
4472
5722
  * evidence is intentionally not authority: every effect rechecks the current
@@ -4498,6 +5748,37 @@ function authorizeMutationFromProjection(projection, request) {
4498
5748
  status: "denied",
4499
5749
  reasonCode: "mutation_contract_item_not_pending"
4500
5750
  };
5751
+ const compatibility = evaluateCompatibility({
5752
+ action: request.action,
5753
+ itemAction: item.semanticAction ?? "generic_run",
5754
+ itemRevision: request.contractItemRevision,
5755
+ currentRevision: item.revision,
5756
+ itemKind: item.kind,
5757
+ itemStatus: item.status,
5758
+ authority: item.authority,
5759
+ legacyFlags: item.legacyFlags,
5760
+ authorityDisposition: item.authorityDisposition,
5761
+ waitAuthorization: item.waitAuthorization,
5762
+ reboundFrom: item.reboundFrom,
5763
+ originalAuthority: item.reboundFrom ? (() => {
5764
+ const original = projection.items.get(item.reboundFrom.itemId);
5765
+ return original ? {
5766
+ semanticAction: original.semanticAction,
5767
+ requestedTarget: original.requestedTarget
5768
+ } : void 0;
5769
+ })() : void 0,
5770
+ targetCaptureStatus: item.targetCaptureStatus,
5771
+ targetSourceKind: item.targetSource?.kind,
5772
+ requestedTarget: item.requestedTarget,
5773
+ adapterSupported: actionHasAdapter(request.action)
5774
+ }, (requested, resolved) => requestedTargetMatchesResolved(request.action, requested, resolved));
5775
+ if (compatibility.status === "incompatible") return compatibility.reasonCodes.includes("action_not_compatible_with_item") ? {
5776
+ status: "denied",
5777
+ reasonCode: "mutation_semantic_action_mismatch"
5778
+ } : {
5779
+ status: "denied",
5780
+ reasonCode: "rebind_does_not_authorize_mutation"
5781
+ };
4501
5782
  if (item.authorityDisposition === "conditional_wait" || item.waitAuthorization) return {
4502
5783
  status: "denied",
4503
5784
  reasonCode: item.authorityDisposition === "conditional_wait" ? "mutation_awaiting_root_condition" : "mutation_awaiting_root_wait"
@@ -4533,6 +5814,10 @@ function authorizeMutationFromProjection(projection, request) {
4533
5814
  status: "denied",
4534
5815
  reasonCode: "mutation_target_clarification_required"
4535
5816
  };
5817
+ if (item.targetSource?.kind === "environment_default") return {
5818
+ status: "denied",
5819
+ reasonCode: "mutation_target_environment_default"
5820
+ };
4536
5821
  const boundedAuthorized = (scope) => requestedTargetAuthorizesMutation(request.action, {
4537
5822
  ...item.requestedTarget,
4538
5823
  scope
@@ -4546,6 +5831,10 @@ function authorizeMutationFromProjection(projection, request) {
4546
5831
  status: "denied",
4547
5832
  reasonCode: "mutation_conflicting_prohibition"
4548
5833
  };
5834
+ if (!itemHoldsExecutionAuthority(item)) return {
5835
+ status: "denied",
5836
+ reasonCode: "mutation_item_not_executable"
5837
+ };
4549
5838
  return {
4550
5839
  status: "authorized",
4551
5840
  reasonCode: "mutation_root_contract_authorized"
@@ -4680,13 +5969,13 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
4680
5969
  }
4681
5970
  return "root_pause_routed";
4682
5971
  }
4683
- const decision = decideTurnBoundary(runtime.projection);
5972
+ const decision = decideTurnBoundary(runtime.projection, rootInstruction?.text);
4684
5973
  if (decision.noProgressClaim) {
4685
- const record$1 = `${NO_PROGRESS_RECORD_PREFIX}${JSON.stringify(decision.noProgressClaim)}`;
5974
+ const record$2 = `${NO_PROGRESS_RECORD_PREFIX}${JSON.stringify(decision.noProgressClaim)}`;
4686
5975
  agent.session.append("user/message", createUserMessage({
4687
5976
  content: [{
4688
5977
  type: "text",
4689
- text: record$1
5978
+ text: record$2
4690
5979
  }],
4691
5980
  source: {
4692
5981
  kind: "plugin",
@@ -4809,7 +6098,7 @@ function sessionHeaderForDigest(session) {
4809
6098
  delegationDepth: typeof raw.delegationDepth === "number" ? raw.delegationDepth : 0
4810
6099
  };
4811
6100
  }
4812
- function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalState, refreshHostLock) {
6101
+ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalState, refreshHostLock, readPrivateRecords, initializePrivateRecords) {
4813
6102
  const projection = createProjection();
4814
6103
  const session = agent.session;
4815
6104
  let pendingRecovery = false;
@@ -4820,11 +6109,14 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
4820
6109
  let observedContractRevision = -1;
4821
6110
  let protocolV4Present = false;
4822
6111
  let protocolV5Present = false;
6112
+ let protocolV6Present = false;
4823
6113
  let realRootInputSeen = false;
4824
6114
  let lifecycle = "armed";
6115
+ let synchronizedOnce = false;
4825
6116
  const continuationAttempts = projection.continuationAttempts;
4826
6117
  const persistenceCorrectionAttempts = projection.persistenceCorrectionAttempts;
4827
6118
  const rebuild = () => {
6119
+ const previousReleaseContracts = projection.releaseContracts.length;
4828
6120
  if (refreshHostLock) hostLock = refreshHostLock();
4829
6121
  const header = session.header;
4830
6122
  const priorRecoveryDigest = projection.lastRecoveryDigest;
@@ -4846,6 +6138,18 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
4846
6138
  sessionHeader
4847
6139
  }, durabilityConfirmed, hostLock);
4848
6140
  Object.assign(projection, derived.projection);
6141
+ if (readPrivateRecords) {
6142
+ let privateSnapshot = readPrivateRecords();
6143
+ if (!synchronizedOnce && events.length === 0 && !privateSnapshot.damaged && !privateSnapshot.anchored && initializePrivateRecords?.()) privateSnapshot = readPrivateRecords();
6144
+ if (projection.releaseContracts.length > 0 && !privateSnapshot.damaged && !privateSnapshot.anchored) if (synchronizedOnce && previousReleaseContracts === 0 && initializePrivateRecords?.()) privateSnapshot = readPrivateRecords();
6145
+ else privateSnapshot = {
6146
+ records: [],
6147
+ damaged: true,
6148
+ anchored: false
6149
+ };
6150
+ applyPrivateLedger(projection, privateSnapshot);
6151
+ }
6152
+ synchronizedOnce = true;
4849
6153
  if (!sessionHeader) {
4850
6154
  projection.integrity = "unknown";
4851
6155
  if (!projection.integrityViolations.includes("session_ref_unavailable")) projection.integrityViolations.push("session_ref_unavailable");
@@ -4864,8 +6168,19 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
4864
6168
  projection.persistenceCorrectionAttempts = persistenceCorrectionAttempts;
4865
6169
  projection.lastRecoveryDigest = priorRecoveryDigest;
4866
6170
  projection.durabilityWatermark = durabilityWatermark;
6171
+ if (projection.boundaryProtocol === 6 && durabilityWatermark === "confirmed") try {
6172
+ const displayOrigins = /* @__PURE__ */ new Map();
6173
+ projection.coreV2 = projectSessionCoreV2(session.snapshotEvents(), projection, displayOrigins);
6174
+ projection.coreV2RequirementOrigins = projection.coreV2 ? displayOrigins : void 0;
6175
+ projection.coreV2Reason = projection.coreV2 ? void 0 : "source_not_projectable";
6176
+ } catch {
6177
+ projection.coreV2 = void 0;
6178
+ projection.coreV2RequirementOrigins = void 0;
6179
+ projection.coreV2Reason = "projection_failed";
6180
+ }
4867
6181
  protocolV4Present = derived.protocolV4Present;
4868
6182
  protocolV5Present = derived.boundaryV5;
6183
+ protocolV6Present = derived.boundaryV6;
4869
6184
  realRootInputSeen = derived.realRootInputSeen;
4870
6185
  lifecycle = lifecyclePhase({
4871
6186
  enabled: projection.enabled,
@@ -4916,6 +6231,9 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
4916
6231
  get protocolV5Present() {
4917
6232
  return protocolV5Present;
4918
6233
  },
6234
+ get protocolV6Present() {
6235
+ return protocolV6Present;
6236
+ },
4919
6237
  sync,
4920
6238
  setEnabled,
4921
6239
  setDurability,
@@ -4957,7 +6275,12 @@ function revalidateCoreLock(config, expected) {
4957
6275
  goalAvailable: false,
4958
6276
  reasonCode: "host_lock_installed_graph_drift"
4959
6277
  };
4960
- return actual;
6278
+ const audited = auditedForegroundRenderers(config.hostLockRuntimeRoot, config.hostLockProfileRoot);
6279
+ return audited.length ? {
6280
+ ...actual,
6281
+ auditedForegroundRenderers: audited,
6282
+ digest: createHash("sha256").update(`dsh.core-host-renderer/v1\0${actual.digest}\0${audited.join(",")}`).digest("hex")
6283
+ } : actual;
4961
6284
  } catch {
4962
6285
  return {
4963
6286
  ...expected,
@@ -4967,6 +6290,41 @@ function revalidateCoreLock(config, expected) {
4967
6290
  };
4968
6291
  }
4969
6292
  }
6293
+ /** Observe one actual Host dispatch through Cordis without joining its gate. */
6294
+ function registerPassiveHostWorkdirObserver(agent, hostLockAtCall, attestedRouteAtCall, sourcedRootAtCall) {
6295
+ if (typeof agent.ctx.on !== "function") return;
6296
+ const pending = /* @__PURE__ */ new WeakMap();
6297
+ agent.ctx.on("tools/pre-execute", async (exec, next) => {
6298
+ if (exec.agent === agent && (exec.name === "bash" || exec.name === "pwsh")) try {
6299
+ const policy = agent.ctx.get("sandboxPolicy");
6300
+ const receipt = captureHostWorkdir(agent.session, exec, hostLockAtCall(), policy, await attestedRouteAtCall(exec.name, agent.ctx.get("shell"), policy), sourcedRootAtCall?.(exec) ?? null);
6301
+ if (receipt) pending.set(exec, receipt);
6302
+ } catch {}
6303
+ return next();
6304
+ });
6305
+ agent.ctx.on("tools/post-execute", async (exec, _result, next) => {
6306
+ const decision = await next();
6307
+ const receipt = pending.get(exec);
6308
+ pending.delete(exec);
6309
+ if (!receipt || exec.agent !== agent) return decision;
6310
+ const context = createUserMessage({
6311
+ content: [{
6312
+ type: "text",
6313
+ text: `${HOST_WORKDIR_PREFIX}${JSON.stringify(receipt)}`
6314
+ }],
6315
+ source: {
6316
+ kind: "plugin",
6317
+ plugin: "context-guard",
6318
+ form: "notice",
6319
+ summary: "read-only Host workdir observation"
6320
+ }
6321
+ });
6322
+ return {
6323
+ ...decision,
6324
+ additionalContexts: [...decision.additionalContexts ?? [], context]
6325
+ };
6326
+ });
6327
+ }
4970
6328
  function apply(ctx, rawConfig = {}, seams = {}) {
4971
6329
  const config = resolveConfig(rawConfig);
4972
6330
  const installedHostLock = seams.hostLock ?? evaluateHostLock(config.hostLockPackages ?? [], {
@@ -4974,7 +6332,14 @@ function apply(ctx, rawConfig = {}, seams = {}) {
4974
6332
  profileKind: config.hostLockProfile
4975
6333
  });
4976
6334
  const runtimes = /* @__PURE__ */ new Map();
6335
+ const privateLedgerRoot = seams.privateLedgerRoot ?? resolvePrivateLedgerRoot(void 0, process.env.DSH_HOME, homedir());
4977
6336
  const hostLocks = /* @__PURE__ */ new Map();
6337
+ const ledgerContext = (agent, fallback = installedHostLock) => ({
6338
+ sessionId: String(agent.session.id),
6339
+ sessionHeader: structuredClone(agent.session.header),
6340
+ cwd: sessionCwd(agent.session) ?? "",
6341
+ hostLockDigest: (hostLocks.get(agent) ?? fallback).digest
6342
+ });
4978
6343
  const registeredAgents = /* @__PURE__ */ new WeakSet();
4979
6344
  const ensure = (agent) => {
4980
6345
  let runtime = runtimes.get(agent);
@@ -4986,7 +6351,7 @@ function apply(ctx, rawConfig = {}, seams = {}) {
4986
6351
  return current;
4987
6352
  };
4988
6353
  const agentHostLock = refreshHostLock();
4989
- runtime = createRuntime(agent, config, agentHostLock, goals ? () => goals.get(agent) : void 0, refreshHostLock);
6354
+ runtime = createRuntime(agent, config, agentHostLock, goals ? () => goals.get(agent) : void 0, refreshHostLock, privateLedgerRoot ? () => readPrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0, privateLedgerRoot ? () => initializePrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0);
4990
6355
  runtimes.set(agent, runtime);
4991
6356
  hostLocks.set(agent, agentHostLock);
4992
6357
  }
@@ -5002,6 +6367,10 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5002
6367
  }
5003
6368
  if (registeredAgents.has(agent)) return;
5004
6369
  registeredAgents.add(agent);
6370
+ registerPassiveHostWorkdirObserver(agent, () => seams.hostLock ?? revalidateCoreLock(config, installedHostLock), (tool, provider, policy) => config.hostLockRuntimeRoot && config.hostLockProfileRoot ? auditedDefaultWorkdirProvider(config.hostLockRuntimeRoot, config.hostLockProfileRoot, tool, provider, policy) : false, (exec) => {
6371
+ runtime.sync();
6372
+ return sourcedNamedTestRoot(runtime.projection, agent.session, exec.arguments);
6373
+ });
5005
6374
  agent.ctx.tools.register(createRebindTool(() => runtime.projection, async () => {
5006
6375
  const durable = await ctx.sessions.flush(agent.session);
5007
6376
  runtime.setDurability(durable);
@@ -5020,33 +6389,11 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5020
6389
  runtime.sync();
5021
6390
  return durable;
5022
6391
  }, () => runtime.markRecoveryNeeded()));
5023
- /**
5024
- * Persist one C10 release record through the plugin-notice channel and make
5025
- * it durable before returning. A record that cannot be flushed is reported
5026
- * as a failure: an unflushed reservation is not an in-flight operation, and
5027
- * an unflushed settlement would let a consumed ticket look unused.
5028
- */
5029
- const persistReleaseRecord = async (toolAgent, prefix, payload) => {
5030
- const target = toolAgent.session;
5031
- target.append.bind(target)("user/message", createUserMessage({
5032
- content: [{
5033
- type: "text",
5034
- text: `${prefix}${JSON.stringify(payload)}`
5035
- }],
5036
- source: {
5037
- kind: "plugin",
5038
- plugin: "context-guard",
5039
- form: "notice",
5040
- summary: boundContextSummary("recording an explicit release record")
5041
- }
5042
- }), { surfaceOp: "append" });
5043
- let durable = false;
5044
- try {
5045
- durable = await ctx.sessions.flush(target);
5046
- } catch {
5047
- durable = false;
5048
- }
5049
- runtime.setDurability(durable);
6392
+ /** Persist release state outside provider-visible Session history. */
6393
+ const persistReleaseRecord = async (toolAgent, kind, payload) => {
6394
+ if (toolAgent.session !== agent.session) return false;
6395
+ if (!sessionCwd(agent.session)) return false;
6396
+ const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), kind, payload);
5050
6397
  runtime.sync();
5051
6398
  return durable;
5052
6399
  };
@@ -5067,12 +6414,13 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5067
6414
  return authorizeMutationFromProjection(runtime.projection, request);
5068
6415
  },
5069
6416
  marketOrigin: optionalMarketOrigin(ctx, agent),
6417
+ hasRestartIntent: (resolutionCallId, serviceId, preGeneration) => hasPrivateRestartIntent(readPrivateLedger(privateLedgerRoot, ledgerContext(agent)), resolutionCallId, serviceId, preGeneration),
5070
6418
  releaseGate: async (request) => {
5071
6419
  runtime.sync();
5072
6420
  const projection = runtime.projection;
5073
6421
  if (!(projection.policy === "release" || projection.releaseContracts.length > 0)) return {
5074
- status: "granted",
5075
- reasonCode: "release_profile_not_adopted"
6422
+ status: "denied",
6423
+ reasonCode: "release_contract_not_adopted"
5076
6424
  };
5077
6425
  const observed = { ...request.observed };
5078
6426
  const declaredRef = releaseContractFor(projection, request.operation)?.candidate.ref;
@@ -5093,12 +6441,19 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5093
6441
  status: "denied",
5094
6442
  reasonCode: decision.reasonCode
5095
6443
  };
5096
- return await persistReleaseRecord(agent, RELEASE_RESERVATION_PREFIX, {
6444
+ const grantedContract = projection.releaseContracts.find((entry) => entry.contractId === decision.contractId);
6445
+ if (!grantedContract) return {
6446
+ status: "denied",
6447
+ reasonCode: "release_state_damaged"
6448
+ };
6449
+ return await persistReleaseRecord(agent, "release_reservation", {
5097
6450
  contractId: decision.contractId,
5098
6451
  operation: request.operation,
5099
6452
  callId: request.callId,
5100
6453
  startedAtSeq: 0,
5101
6454
  status: "in_flight",
6455
+ contract_sha256: privateLedgerContractDigest(grantedContract),
6456
+ target_sha256: privateLedgerTargetDigest(request.resolvedTarget),
5102
6457
  ...observed.artifactSri !== void 0 ? { observedArtifactSri: observed.artifactSri } : {}
5103
6458
  }) ? {
5104
6459
  status: "granted",
@@ -5115,40 +6470,41 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5115
6470
  const reservation = reservationFor(runtime.projection, contractId, request.callId);
5116
6471
  let outcome = request.effect === "not_effected" ? "not_effected" : "unknown";
5117
6472
  if (request.effect === "completed" && contract) outcome = readbackSettlesContract(contract, request.readback, reservation?.observedArtifactSri) === "settled" ? "settled" : "unknown";
5118
- await persistReleaseRecord(agent, RELEASE_SETTLEMENT_PREFIX, {
6473
+ await persistReleaseRecord(agent, "release_settlement", {
5119
6474
  contractId,
5120
6475
  operation: request.operation,
5121
6476
  callId: request.callId,
5122
6477
  settledAtSeq: 0,
5123
6478
  readback: request.readback,
5124
- outcome
6479
+ outcome,
6480
+ settlement_source: "effect"
5125
6481
  });
5126
6482
  },
5127
6483
  persistRestartIntent: async (toolAgent, intent) => {
5128
- const session = toolAgent.session;
5129
- session.append.bind(session)("user/message", createUserMessage({
5130
- content: [{
5131
- type: "text",
5132
- text: `${RESTART_INTENT_PREFIX}${JSON.stringify({
5133
- resolution_call_id: intent.resolutionCallId,
5134
- service_id: intent.serviceId,
5135
- pre_generation: intent.preGeneration
5136
- })}`
5137
- }],
5138
- source: {
5139
- kind: "plugin",
5140
- plugin: "context-guard",
5141
- form: "notice",
5142
- summary: boundContextSummary("persisting a restart handoff intent")
5143
- }
5144
- }), { surfaceOp: "append" });
5145
- const durable = await ctx.sessions.flush(session);
5146
- runtime.setDurability(durable);
6484
+ if (toolAgent.session !== agent.session) return false;
6485
+ if (!sessionCwd(agent.session)) return false;
6486
+ const snapshot = readPrivateLedger(privateLedgerRoot, ledgerContext(agent));
6487
+ if (snapshot.damaged || !snapshot.anchored) return false;
6488
+ const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), "restart_intent", {
6489
+ resolution_call_id: intent.resolutionCallId,
6490
+ service_id: intent.serviceId,
6491
+ pre_generation: intent.preGeneration
6492
+ });
5147
6493
  runtime.sync();
5148
6494
  return durable;
5149
6495
  }
5150
6496
  };
5151
6497
  agent.ctx.tools.register(createEvidenceTool(evidenceOptions));
6498
+ agent.ctx.tools.register(createNativeFileObserver({
6499
+ fs: ctx.fs,
6500
+ flush: (session) => ctx.sessions.flush(session)
6501
+ }));
6502
+ agent.ctx.tools.register(createNativeGitObserver({ flush: (session) => ctx.sessions.flush(session) }));
6503
+ agent.ctx.tools.register(createTestReadinessObserver({
6504
+ getProjection: () => runtime.projection,
6505
+ fs: ctx.fs,
6506
+ flush: (session) => ctx.sessions.flush(session)
6507
+ }));
5152
6508
  agent.ctx.tools.register(createActionTool(evidenceOptions));
5153
6509
  agent.ctx.tools.register(createPrepareTool({
5154
6510
  getProjection: () => runtime.projection,
@@ -5180,13 +6536,14 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5180
6536
  getProjection: () => runtime.projection,
5181
6537
  fetcher: evidenceOptions.fetcher,
5182
6538
  ...evidenceOptions.allowLoopbackHttpRegistry ? { allowLoopbackHttpRegistry: true } : {},
5183
- persistSettlement: async (request) => persistReleaseRecord(request.agent, RELEASE_SETTLEMENT_PREFIX, {
6539
+ persistSettlement: async (request) => persistReleaseRecord(request.agent, "release_settlement", {
5184
6540
  contractId: request.contractId,
5185
6541
  operation: request.operation,
5186
6542
  callId: request.callId,
5187
6543
  settledAtSeq: 0,
5188
6544
  readback: request.readback,
5189
- outcome: request.outcome
6545
+ outcome: request.outcome,
6546
+ settlement_source: "reconcile"
5190
6547
  })
5191
6548
  }));
5192
6549
  agent.ctx.tools.register(createExternalOperationTool((id, toolAgent) => readExternalOperation(ctx, toolAgent, id), () => evaluateExternalWaitCapability(hostLocks.get(agent) ?? installedHostLock)));
@@ -5201,11 +6558,13 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5201
6558
  if (decision.kind !== "enter") return decision;
5202
6559
  const injected = [];
5203
6560
  const delegated = isDelegatedSession(agent.session);
5204
- let boundaryPending = !runtime.protocolV5Present;
6561
+ let boundaryPending = !runtime.protocolV6Present;
5205
6562
  const firstStep = previewFirstStepInjection({
5206
6563
  activation: config.activation,
5207
6564
  enabled: runtime.projection.enabled,
5208
6565
  boundaryV5Present: runtime.protocolV5Present,
6566
+ boundaryV6Present: runtime.protocolV6Present,
6567
+ targetProtocol: 6,
5209
6568
  boundaryPresent: runtime.protocolV4Present,
5210
6569
  delegated,
5211
6570
  policy: runtime.projection.policy
@@ -5223,7 +6582,7 @@ function apply(ctx, rawConfig = {}, seams = {}) {
5223
6582
  if (recovery && digest$2 !== runtime.projection.lastRecoveryDigest) {
5224
6583
  runtime.projection.lastRecoveryDigest = digest$2;
5225
6584
  if (boundaryPending && !delegated) {
5226
- injected.push(pluginNoticeMessage(PROTOCOL_V5_NOTICE, "Context Guard recorded a replay version boundary"));
6585
+ injected.push(pluginNoticeMessage(PROTOCOL_V6_NOTICE, "Context Guard recorded a replay version boundary"));
5227
6586
  boundaryPending = false;
5228
6587
  }
5229
6588
  injected.push(createUserMessage({
@@ -5344,12 +6703,12 @@ function optionalGoalService(ctx, agent) {
5344
6703
  }
5345
6704
  function normalizeGoalState(value) {
5346
6705
  if (!value || typeof value !== "object") return void 0;
5347
- const record$1 = value;
5348
- const goal = record$1.goal && typeof record$1.goal === "object" ? record$1.goal : record$1;
6706
+ const record$2 = value;
6707
+ const goal = record$2.goal && typeof record$2.goal === "object" ? record$2.goal : record$2;
5349
6708
  const id = goal.id;
5350
6709
  const revision = goal.revision;
5351
6710
  const phase = goal.phase;
5352
- const activation = record$1.activation ?? goal.activation;
6711
+ const activation = record$2.activation ?? goal.activation;
5353
6712
  if (typeof id !== "string" || typeof revision !== "number") return void 0;
5354
6713
  if (![
5355
6714
  "active",
@@ -5367,4 +6726,112 @@ function normalizeGoalState(value) {
5367
6726
  }
5368
6727
 
5369
6728
  //#endregion
5370
- export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION, ALPHA2_DSHMARKET_139_HOST_PACKAGES, ALPHA2_HOST_PACKAGES, ALPHA3_HOST_PACKAGES, BASE_HOST_PACKAGES, BOUNDED_ARTIFACT_TYPES, CAPTURE_V042_NOTICE, CERTIFICATE_VERSION, CERTIFICATE_VERSION_V2, CLEANUP_CONDITION_RULE, CLEANUP_CONDITION_RULE_COMPACT, CLEANUP_CONDITION_RULE_SHORT, COMMAND_SURFACE_MANIFEST, CONFIRM_LINE_PATTERN, CONTROL_RECORD_PREFIX, Config, DEFAULT_DELEGATION_TOOL_NAMES, DEFAULT_HOST_LOCK, DEFAULT_RECOVERY_CHAR_BUDGET, DEPENDENCY_FREE_ONLY_CONDITION, EXPECTED_HOST_PACKAGES, FIRST_STEP_GUIDANCE, GIT_COMMAND_MANIFEST_IDS, GIT_COMMAND_TEMPLATES, GOAL_HOST_PACKAGES, HOST_CAPABILITY_PACKAGE_GROUPS, HOST_COHORTS, HostProfileError, LATEST_SUPPORTED_HOST_VERSION, LEGACY_HOST_COHORTS, MIN_RECOVERY_CHAR_BUDGET, MIN_SUPPORTED_HOST_VERSION, NO_PROGRESS_RECORD_PREFIX, NO_PROGRESS_TURNS_BEFORE_STOP, PROOF_CAPABILITY_MATRIX, PROOF_KINDS, PROOF_KINDS_V2, PROOF_MANIFEST_DOMAIN_V2, PROOF_PROTOCOL_VERSION, PROOF_PROTOCOL_VERSION_V2, PROTOCOL_V3_NOTICE, PROTOCOL_V4_NOTICE, PROTOCOL_V5_NOTICE, RC015_HOST_PACKAGES, RC015_RC2_HOST_PACKAGES, RC1_HOST_PACKAGES, SEMANTIC_ACTIONS, SESSION_API_UNSUPPORTED, SESSION_EVENT_ENVELOPE_INVALID, STATEFUL_ACTIONS, STOP_PROTOCOL_VERSION, STOP_PROTOCOL_VERSION_V2, SUPPORTED_EVIDENCE_ADAPTERS, SUPPORTED_HOST_RANGE, SUPPORTED_HOST_VERSIONS, SessionApiError, actionCompatible, actionHasCertificationPath, admissibleForRemoval, apply, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, capabilityConsequence, capabilityFactOf, capabilityRemedyPhrase, captureClause, captureItem, carriesCleanupCondition, certifyCheckpoint, claimedBatchHasRealRootInput, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, cleanupConditionFor, closingHint, combineHostPolicy, commitIndexSnapshotDigest, commitTreeSnapshotDigest, compareHostVersions, confirmRebind, createGitPrestateEnvelope, createProjection, createProofManifest, createProofManifestV2, currentContractDigest, decideTurnBoundary, decideTurnStopping, decisionBoundaryKey, deriveItemDiagnosis, deriveProjection, digestStrings, effectuateBoundary, evaluateExternalWaitCapability, evaluateHostCapability, evaluateHostLock, evaluateMinimumHostVersion, evaluateToolSurfaceCapability, evidenceAvailabilityReason, evidenceCoverage, evidenceFromPersistedToolResult, evidenceMatchesItem, executeRevalidatedGitEffect, extractArtifactPaths, extractMethod, extractOperation, extractTextContent, extractToolSubject, firstStepGuidance, gitCommandMatchesTarget, goalCompletionDenial, hasCurrentCertificate, hostLockContextFromComposedDump, hostLockRowsFromComposedDump, hostVersionFromPackages, inject, injectActiveProfileHostLock, inspectTargetHostGraph, interpretClause, interpretMessage, isCurrentAcceptedBoundary, isDeterministicCheck, isExecutableItem, isFrozenV042RebindResponse, isInformationalMessage, isOpenObligation, isRootPauseRequest, isRunExecutable, isStatefulAction, isVerifyingCapability, isWholeTaskCompletionClaim, itemDiagnosis, kindOfScope, latestAssistantText, latestRootInstruction, lifecyclePhase, maskCodeSpans, name, namedActions, normalizeClause, observeAssistantOutcome, openItems, packageRowsFromActiveGraph, packageRowsFromPnpmLock, parseConfirmationMessage, parseGitCommandManifest, parseHostVersion, parsePwshCommand, parseShellCommand, partialFailureOf, previewFirstStepInjection, progressFingerprint, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualifyBoundary, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, relevantEvidence, removalIsComplete, removalIsPartiallyKnown, renderRecoveryPacket, replayRebindResult, requestedIdentityKey, requestedTargetAuthorizesMutation, requestedTargetMatchesResolved, requiredSubjectsOf, resolveActiveProfileHostLock, resolveInstalledHostLock, revalidateGitPrestate, sanitizeClauseText, sanitizeUrl, satisfiesSupportedHostRange, scopeCoverageDigest, segmentAuthorityBlocks, segmentClauses, selectHostCohort, semanticActionFromCommand, semanticActionFromText, semanticActionOfScope, sessionQuery, sessionQueryV2, sha256, snapshotSessionEvents, statefulActionsOfScope, supersedeItem, validateActionManifest, validateActionTarget, validateManifest, validateProofManifest, validateProofManifestV2, verifiedLinearCommitReadback, verifyComposedHostLockDump, withDurability };
6729
+ //#region src/raw-replay.ts
6730
+ /** Local synthetic replay using the actual Session, derivation and registered
6731
+ * Stop handler. It neither executes tools nor asserts a real model outcome. */
6732
+ async function replayRawV2(input) {
6733
+ const cwd = input.cwd ?? "/work";
6734
+ const id = SessionId("raw-v2-replay");
6735
+ const session = Session.create(id, void 0, {
6736
+ version: SESSION_FORMAT_VERSION,
6737
+ isSeeded: false,
6738
+ id,
6739
+ createdAt: 1,
6740
+ cwd
6741
+ });
6742
+ session.append("user/message", createUserMessage({
6743
+ content: [{
6744
+ type: "text",
6745
+ text: PROTOCOL_V6_NOTICE
6746
+ }],
6747
+ source: {
6748
+ kind: "plugin",
6749
+ plugin: "context-guard",
6750
+ form: "notice",
6751
+ summary: "v6 replay boundary"
6752
+ }
6753
+ }), { surfaceOp: "append" });
6754
+ session.append("turn/start", { turn: 1 });
6755
+ session.append("user/message", createUserMessage({
6756
+ content: [{
6757
+ type: "text",
6758
+ text: input.root
6759
+ }],
6760
+ source: { kind: "user" }
6761
+ }), { surfaceOp: "append" });
6762
+ const appendEvent = session.append.bind(session);
6763
+ for (const event of input.events ?? []) {
6764
+ if (event.type === "turn/end") throw new Error("turn/end is emitted only after the Stop callback in this replay");
6765
+ appendEvent(event.type, event.data, event.type === "tool/call" ? void 0 : { surfaceOp: "append" });
6766
+ }
6767
+ session.append("assistant/message", {
6768
+ turn: 1,
6769
+ step: 1,
6770
+ message: {
6771
+ role: "assistant",
6772
+ content: [{
6773
+ type: "text",
6774
+ text: input.final
6775
+ }]
6776
+ }
6777
+ }, { surfaceOp: "append" });
6778
+ const lock = evaluateHostLock(EXPECTED_HOST_PACKAGES, {
6779
+ platform: "posix",
6780
+ profileKind: "web"
6781
+ });
6782
+ const steers = [];
6783
+ const agent = {
6784
+ session,
6785
+ steer: (message) => {
6786
+ steers.push(message);
6787
+ }
6788
+ };
6789
+ const runtime = createRuntime(agent, { activation: "always" }, lock, () => void 0);
6790
+ runtime.setDurability(true);
6791
+ runtime.sync();
6792
+ const snapshot = sessionCoreSnapshot(session.snapshotEvents(), runtime.projection);
6793
+ const stopCore = runtime.projection.coreV2 ?? null;
6794
+ const stop = await handleGuardTurnStopping(agent, runtime, {
6795
+ flush: async () => true,
6796
+ hostSupported: true,
6797
+ readExternalOperation: () => void 0
6798
+ });
6799
+ session.append("turn/end", {
6800
+ turn: 1,
6801
+ reason: { kind: "completed" }
6802
+ });
6803
+ runtime.sync();
6804
+ const projection = runtime.projection;
6805
+ const postSnapshot = sessionCoreSnapshot(session.snapshotEvents(), projection);
6806
+ return {
6807
+ stop_core_snapshot: snapshot ?? null,
6808
+ stop_core_projection: stopCore,
6809
+ stop,
6810
+ post_turn_core_snapshot: postSnapshot ?? null,
6811
+ post_turn_core_projection: projection.coreV2 ?? null,
6812
+ goal_complete_denial: goalCompletionDenial(projection, "update_goal", {
6813
+ action: "complete",
6814
+ goal_id: projection.currentGoalRef?.id,
6815
+ revision: projection.currentGoalRef?.revision
6816
+ }) ?? null,
6817
+ assistant_observation: observeAssistantOutcome(input.final),
6818
+ steers: steers.length,
6819
+ items: [...projection.items.values()].map((item) => ({
6820
+ id: item.id,
6821
+ status: item.status,
6822
+ action: item.semanticAction,
6823
+ authority: item.authority,
6824
+ disposition: item.authorityDisposition,
6825
+ review: item.needsReview?.reason ?? null
6826
+ })),
6827
+ durable_seq: session.seq,
6828
+ event_types: session.snapshotEvents().map((event) => ({
6829
+ seq: event.seq,
6830
+ type: event.type
6831
+ })),
6832
+ boundary_protocol: projection.boundaryProtocol
6833
+ };
6834
+ }
6835
+
6836
+ //#endregion
6837
+ export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION, ALPHA2_DSHMARKET_139_HOST_PACKAGES, ALPHA2_HOST_PACKAGES, ALPHA3_HOST_PACKAGES, BASE_HOST_PACKAGES, BOUNDED_ARTIFACT_TYPES, CAPTURE_V042_NOTICE, CERTIFICATE_VERSION, CERTIFICATE_VERSION_V2, CLEANUP_CONDITION_RULE, CLEANUP_CONDITION_RULE_COMPACT, CLEANUP_CONDITION_RULE_SHORT, COMMAND_SURFACE_MANIFEST, CONFIRM_LINE_PATTERN, CONTROL_RECORD_PREFIX, Config, DEFAULT_DELEGATION_TOOL_NAMES, DEFAULT_HOST_LOCK, DEFAULT_RECOVERY_CHAR_BUDGET, DEPENDENCY_FREE_ONLY_CONDITION, EXPECTED_HOST_PACKAGES, FIRST_STEP_GUIDANCE, GIT_COMMAND_MANIFEST_IDS, GIT_COMMAND_TEMPLATES, GOAL_HOST_PACKAGES, GRANTED_QUALIFICATION, HOST_CAPABILITY_PACKAGE_GROUPS, HOST_COHORTS, HostProfileError, LATEST_SUPPORTED_HOST_VERSION, LEGACY_HOST_COHORTS, LEGACY_QUALIFICATION, MIN_RECOVERY_CHAR_BUDGET, MIN_SUPPORTED_HOST_VERSION, NO_PROGRESS_RECORD_PREFIX, NO_PROGRESS_TURNS_BEFORE_STOP, PROOF_CAPABILITY_MATRIX, PROOF_KINDS, PROOF_KINDS_V2, PROOF_MANIFEST_DOMAIN_V2, PROOF_PROTOCOL_VERSION, PROOF_PROTOCOL_VERSION_V2, PROTOCOL_V3_NOTICE, PROTOCOL_V4_NOTICE, PROTOCOL_V5_NOTICE, PROTOCOL_V6_NOTICE, RC015_HOST_PACKAGES, RC015_RC2_HOST_PACKAGES, RC1_HOST_PACKAGES, SEMANTIC_ACTIONS, SESSION_API_UNSUPPORTED, SESSION_EVENT_ENVELOPE_INVALID, STATEFUL_ACTIONS, STOP_PROTOCOL_VERSION, STOP_PROTOCOL_VERSION_V2, SUPPORTED_EVIDENCE_ADAPTERS, SUPPORTED_HOST_RANGE, SUPPORTED_HOST_VERSIONS, SessionApiError, actionCompatible, actionHasCertificationPath, actionVerbMatches, activeRendererModule, admissibleForRemoval, apply, applyUpgradeEligibility, assessmentAction, assessmentOutcomePredicate, auditedDefaultWorkdirHost, auditedDefaultWorkdirProvider, auditedForegroundRenderers, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, capabilityConsequence, capabilityFactOf, capabilityRemedyPhrase, captureClause, captureItem, carriesCleanupCondition, certifyCheckpoint, claimedBatchHasRealRootInput, clarifiedSpanOf, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, clauseAsksOwnQuestion, clauseIsGoverned, clauseIsProtected, cleanupConditionFor, closingHint, combineHostPolicy, commitIndexSnapshotDigest, commitTreeSnapshotDigest, compareHostVersions, confirmRebind, createGitPrestateEnvelope, createProjection, createProofManifest, createProofManifestV2, currentActionBases, currentContractDigest, decideTurnBoundary, decideTurnStopping, decisionBoundaryKey, deriveItemDiagnosis, deriveProjection, digestStrings, effectuateBoundary, environmentDefaultRepositoryTarget, evaluateExternalWaitCapability, evaluateHostCapability, evaluateHostLock, evaluateMinimumHostVersion, evaluateToolSurfaceCapability, evidenceAvailabilityReason, evidenceCoverage, evidenceFromPersistedToolResult, evidenceMatchesItem, executeRevalidatedGitEffect, explanationHasActionResidue, extractArtifactPaths, extractMethod, extractOperation, extractTextContent, extractToolSubject, firstStepGuidance, firstStepGuidanceV6, gitCommandMatchesTarget, goalCompletionDenial, governedClauseRestrictsExecution, hasCurrentCertificate, hasOrderedCoordination, hasQuestionScope, hasWorkPredicate, hostLockContextFromComposedDump, hostLockRowsFromComposedDump, hostVersionFromPackages, inject, injectActiveProfileHostLock, inspectTargetHostGraph, interpretClause, interpretMessage, introducesActionClause, isCurrentAcceptedBoundary, isDeterministicCheck, isExecutableItem, isExplanationScope, isFrozenV042RebindResponse, isInformationalFragment, isInformationalMessage, isOpenObligation, isQuestionScopeNeedingReview, isRestatement, isRootPauseRequest, isRunExecutable, isStatefulAction, isVerifyingCapability, isWholeTaskCompletionClaim, itemDiagnosis, itemHoldsExecutionAuthority, kindOfScope, latestAssistantText, latestRootInstruction, legacyQuestionReadingIsInformational, legacyRecordsNeedingReview, lifecyclePhase, maskCodeSpans, maskQuotedSpans, name, namedActions, normalizeClause, observeAssistantOutcome, openItems, opensConditionLead, opensWithDirective, packageRowsFromActiveGraph, packageRowsFromPnpmLock, parseConfirmationMessage, parseGitCommandManifest, parseHostVersion, parsePwshCommand, parseShellCommand, partialFailureOf, persistedToolResultStatus, presentExplanationHead, previewFirstStepInjection, progressFingerprint, projectCoreV2, projectSessionCoreV2, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualificationOfClause, qualifyBoundary, questionHeadsClause, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, relevantEvidence, removalIsComplete, removalIsPartiallyKnown, renderRecoveryPacket, replayRawV2, replayRebindResult, reportingHeadGoverns, requestedIdentityKey, requestedTargetAuthorizesMutation, requestedTargetMatchesResolved, requiredSubjectsOf, resolveActiveProfileHostLock, resolveInstalledHostLock, restatedContentOf, revalidateGitPrestate, rootLocatorFlavor, sanitizeClauseText, sanitizeUrl, satisfiesSupportedHostRange, scopeCoverageDigest, segmentAuthorityBlocks, segmentClauses, selectHostCohort, semanticActionFromCommand, semanticActionFromText, semanticActionOfScope, sessionQuery, sessionQueryV2, sha256, snapshotSessionEvents, splitTextFragments, statefulActionsOfScope, supersedeItem, testOutcomePredicate, v6TestPredicate, validateActionManifest, validateActionTarget, validateManifest, validateProofManifest, validateProofManifestV2, verbIsNegated, verifiedLinearCommitReadback, verifyComposedHostLockDump, withDurability };