dsh-completion-guard 0.6.0 → 0.6.2

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,4 +1,4 @@
1
- import { $ as isDeterministicCheck, $n as deriveItemDiagnosis, $t as proofDigestV2, A as previewFirstStepInjection, An as isWholeTaskCompletionClaim, Ar as STOP_PROTOCOL_VERSION_V2, At as evaluateMinimumHostVersion, B as RELEASE_SETTLEMENT_PREFIX, Bn as qualifyBoundary, Br as validateActionManifest, Bt as PROOF_CAPABILITY_MATRIX, C as gitCommandMatchesTarget, Cn as NO_PROGRESS_RECORD_PREFIX, Cr as ACTION_MANIFEST_VERSION, Ct as hostVersionFromPackages, D as FIRST_STEP_GUIDANCE, Dn as decideTurnStopping, Dr as SEMANTIC_ACTIONS, Dt as SUPPORTED_HOST_RANGE, E as verifiedLinearCommitReadback, En as decideTurnBoundary, Er as CERTIFICATE_VERSION_V2, Et as MIN_SUPPORTED_HOST_VERSION, F as PROTOCOL_V5_NOTICE, Fn as goalCompletionDenial, Fr as requestedIdentityKey, Ft as RC1_HOST_PACKAGES, G as releaseContractFor, Gn as proposeRebindOutcome, Gr as classifyUserInteraction, Gt as PROOF_PROTOCOL_VERSION_V2, H as inFlightReservation, Hn as createProjection, Hr as COMMAND_SURFACE_MANIFEST, Ht as PROOF_KINDS_V2, I as deriveProjection, In as hasCurrentCertificate, Ir as requestedTargetAuthorizesMutation, It as ALPHA3_HOST_PACKAGES, J as reservationFor, Jn as rebindResponse, Jr as normalizeClause, Jt as canonicalProjection, K as releaseCoverage, Kn as proposeRebindV042, Kr as canonicalizePath, Kt as bindProofToProjection, L as RELEASE_OPERATIONS, Ln as availableBoundaryQualifications, Lr as requestedTargetMatchesResolved, Lt as authorityCaptureCounts, M as DEFAULT_DELEGATION_TOOL_NAMES, Mn as latestRootInstruction, Mr as actionCompatible, Mt as satisfiesSupportedHostRange, N as PROTOCOL_V3_NOTICE, Nn as observeAssistantOutcome, Nr as boundedArtifactChoiceMatches, Nt as RC015_RC2_HOST_PACKAGES, O as claimedBatchHasRealRootInput, On as decisionBoundaryKey, Or as STATEFUL_ACTIONS, Ot as SUPPORTED_HOST_VERSIONS, P as PROTOCOL_V4_NOTICE, Pn as progressFingerprint, Pr as isStatefulAction, Pt as RC015_HOST_PACKAGES, Q as extractToolSubject, Qn as parseConfirmationMessage, Qt as proofDigest, R as RELEASE_OPERATION_SURFACES, Rn as effectuateBoundary, Rr as semanticActionFromCommand, Rt as segmentAuthorityBlocks, S as executeRevalidatedGitEffect, Sn as CONTROL_RECORD_PREFIX, Sr as ACTION_MANIFEST, St as evaluateToolSurfaceCapability, T as revalidateGitPrestate, Tn as classifyCompletionClaim, Tr as CERTIFICATE_VERSION, Tt as LATEST_SUPPORTED_HOST_VERSION, U as normalizeReleaseContract, Un as confirmRebind, Ur as validateManifest, Ut as PROOF_MANIFEST_DOMAIN_V2, V as contractById, Vn as currentContractDigest, Vr as validateActionTarget, Vt as PROOF_KINDS, W as readbackSettlesContract, Wn as proposeRebind, Wr as classifyTaskIntent, Wt as PROOF_PROTOCOL_VERSION, X as evidenceFromPersistedToolResult, Xn as CONFIRM_LINE_PATTERN, Xr as sanitizeUrl, Xt as createProofManifestV2, Y as supersedeItem, Yn as replayRebindResult, Yr as sanitizeClauseText, Yt as createProofManifest, Z as extractTextContent, Zn as isFrozenV042RebindResponse, Zr as sha256, Zt as proofCapabilityReport, _ as GIT_COMMAND_MANIFEST_IDS, _n as renderRecoveryPacket, _r as namedActions, _t as bindExecutableIdentity, a as injectActiveProfileHostLock, an as scopeCoverageDigest, ar as classifyClause, at as ACTIVE_HOST_COHORT_ID, b as commitTreeSnapshotDigest, bn as evidenceMatchesItem, br as canonicalRegistryBase, bt as evaluateHostCapability, c as packageRowsFromPnpmLock, cn as validateProofManifest, cr as extractOperation, ct as ALPHA2_DSHMARKET_139_HOST_PACKAGES, d as resolveInstalledHostLock, dn as certificateClosure, dr as interpretClause, dt as DEFAULT_HOST_LOCK, en as proofEvidenceConstraints, er as evidenceAvailabilityReason, et as withDurability, f as verifyComposedHostLockDump, fn as DEFAULT_RECOVERY_CHAR_BUDGET, fr as interpretMessage, ft as EXPECTED_HOST_PACKAGES, g as snapshotSessionEvents, gn as recoveryDigest, gr as maskCodeSpans, gt as LEGACY_HOST_COHORTS, h as SessionApiError, hn as openItems, hr as kindOfScope, ht as HOST_COHORTS, i as hostLockRowsFromComposedDump, in as requiredSubjectsOf, ir as captureItem, it as parseShellCommand, j as CAPTURE_V042_NOTICE, jn as latestAssistantText, jr as SUPPORTED_EVIDENCE_ADAPTERS, jt as parseHostVersion, k as lifecyclePhase, kn as isRootPauseRequest, kr as STOP_PROTOCOL_VERSION, kt as compareHostVersions, l as readActiveHostGraph, ln as validateProofManifestV2, lr as isInformationalMessage, lt as ALPHA2_HOST_PACKAGES, m as SESSION_EVENT_ENVELOPE_INVALID, mn as closingHint, mr as isOpenObligation, mt as HOST_CAPABILITY_PACKAGE_GROUPS, n as combineHostPolicy, nn as proofOperationMatches, nr as relevantEvidence, nt as isRunExecutable, o as inspectTargetHostGraph, on as sessionQuery, or as extractArtifactPaths, ot as ACTIVE_HOST_COHORT_IDS, p as SESSION_API_UNSUPPORTED, pn as MIN_RECOVERY_CHAR_BUDGET, pr as isExecutableItem, pt as GOAL_HOST_PACKAGES, q as releasePreEffectDecision, qn as rebindAttemptKey, qr as digestStrings, qt as bindProofV2ToProjection, r as hostLockContextFromComposedDump, rn as proofV2Rejection, rr as captureClause, rt as parsePwshCommand, s as packageRowsFromActiveGraph, sn as sessionQueryV2, sr as extractMethod, st as ACTIVE_HOST_LAUNCHER_VERSION, t as HostProfileError, tn as proofHostSurfacesOf, tr as itemDiagnosis, tt as canonicalArgvFromCommand, u as resolveActiveProfileHostLock, un as certifiableOpenItems, ur as segmentClauses, ut as BASE_HOST_PACKAGES, v as GIT_COMMAND_TEMPLATES, vn as bindingSatisfies, vr as semanticActionOfScope, vt as bindLiveGoalCapability, w as parseGitCommandManifest, wn as NO_PROGRESS_TURNS_BEFORE_STOP, wr as BOUNDED_ARTIFACT_TYPES, wt as selectHostCohort, x as createGitPrestateEnvelope, xn as isVerifyingCapability, xr as npmEscapedPackageName, xt as evaluateHostLock, y as commitIndexSnapshotDigest, yn as evidenceCoverage, yr as statefulActionsOfScope, yt as evaluateExternalWaitCapability, z as RELEASE_RESERVATION_PREFIX, zn as isCurrentAcceptedBoundary, zr as semanticActionFromText, zt as certifyCheckpoint } from "./domain-COehX7MB.js";
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";
2
2
  import { defineTool } from "@deepseek-ai/dsh-tools";
3
3
  import { createHash } from "node:crypto";
4
4
  import { basename, delimiter, dirname, isAbsolute, join, resolve } from "node:path";
@@ -72,6 +72,8 @@ const LANES = [
72
72
  "available_qualifications"
73
73
  ];
74
74
  const MAX_BYTES = 12288;
75
+ /** Inline item-row bytes; a larger row is summarized, never silently dropped. */
76
+ const ITEM_ROW_BUDGET = 1850;
75
77
  const size = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
76
78
  const digest$1 = (value) => sha256(JSON.stringify(value));
77
79
  const lookup = (id) => id.length <= 128 ? id : `sha256:${sha256(id)}`;
@@ -178,13 +180,14 @@ function checkpointPage(p, query, full) {
178
180
  detail_query: "Use detail_id and detail_offset; evidence_scope=history includes non-citable evidence."
179
181
  };
180
182
  const summarize = (row) => {
181
- if (size(row) <= 1800) return row;
183
+ if (size(row) <= ITEM_ROW_BUDGET) return row;
182
184
  return {
183
185
  id: String(row.id ?? row.item_id).slice(0, 128),
184
186
  reason_code: row.reason_code,
185
187
  certifiable: row.certifiable,
186
188
  next_step: typeof row.next_step === "string" ? row.next_step.slice(0, 240) : void 0,
187
189
  adapter_disposition: row.adapter_disposition,
190
+ ...row.binding_template !== void 0 ? { binding_template: row.binding_template } : {},
188
191
  omitted: true,
189
192
  detail_id: lookup(String(row.id ?? row.item_id))
190
193
  };
@@ -310,6 +313,8 @@ function openItemForTool(projection, item) {
310
313
  const action = item.semanticAction ?? "generic_run";
311
314
  const spec = ACTION_MANIFEST.actions[action];
312
315
  const template = bindingTemplate(projection, item);
316
+ const diagnosis = deriveItemDiagnosis(projection, item);
317
+ const compact = itemDiagnosis(projection, item);
313
318
  return {
314
319
  id: item.id,
315
320
  revision: item.revision,
@@ -321,9 +326,17 @@ function openItemForTool(projection, item) {
321
326
  kind: item.kind,
322
327
  semantic_action: action,
323
328
  requested_target: targetForTool(item.requestedTarget),
324
- ...itemDiagnosis(projection, item),
325
- producer_disposition: ACTION_MANIFEST.actions[action].evidenceProducer,
329
+ certifiable: compact.certifiable,
330
+ reason_code: diagnosis.reason_code,
331
+ next_step: diagnosis.capability.remedy === "await_root_input" ? (diagnosis.next_action.resume_condition ?? capabilityRemedyPhrase(diagnosis.capability.remedy)).slice(0, 240) : capabilityRemedyPhrase(diagnosis.capability.remedy),
326
332
  ...item.targetCaptureStatus ? { target_capture_status: item.targetCaptureStatus } : {},
333
+ capability: {
334
+ action_supported: diagnosis.capability.actionSupported,
335
+ certifiable: diagnosis.capability.certifiable,
336
+ gap: diagnosis.capability.gap,
337
+ remedy: diagnosis.capability.remedy
338
+ },
339
+ producer_disposition: ACTION_MANIFEST.actions[action].evidenceProducer,
327
340
  ...item.targetCaptureReasonCode ? { target_capture_reason_code: item.targetCaptureReasonCode } : {},
328
341
  predicate: {
329
342
  predicate_id: spec.predicateId,
@@ -734,7 +747,21 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
734
747
  ...evidence.adapterId ? { adapter_id: evidence.adapterId } : {},
735
748
  ...evidence.adapterVersion ? { adapter_version: evidence.adapterVersion } : {},
736
749
  adapter_disposition: evidenceAvailabilityReason(evidence) === void 0 ? "citable" : "unavailable",
737
- ...evidenceAvailabilityReason(evidence) ? { reason_code: evidenceAvailabilityReason(evidence) } : {}
750
+ ...evidenceAvailabilityReason(evidence) ? { reason_code: evidenceAvailabilityReason(evidence) } : {},
751
+ ...evidence.processFacts ? { process_facts: {
752
+ host_tool_returned: evidence.processFacts.hostToolReturned,
753
+ declared_exit_code: evidence.processFacts.declaredExitCode === "unknown" ? "unknown" : evidence.processFacts.declaredExitCode,
754
+ terminal_marker_read: evidence.processFacts.terminalMarkerRead,
755
+ process_outcome: evidence.processFacts.outcome,
756
+ outcome_reason: evidence.processFacts.outcomeReason,
757
+ source: evidence.processFacts.source,
758
+ frozen_outcome_conflict: evidence.processFacts.frozenOutcomeConflict,
759
+ operation_attribution: evidence.processFacts.operationAttribution,
760
+ ...evidence.processFacts.declaredOperationResults ? { declared_operation_results: evidence.processFacts.declaredOperationResults.map((row) => ({
761
+ action: row.action,
762
+ outcome: row.outcome
763
+ })) } : {}
764
+ } } : {}
738
765
  }));
739
766
  return checkpointPage(projection, args, {
740
767
  status: result.status,
@@ -1101,6 +1128,22 @@ function actionPreparation(action) {
1101
1128
  //#region src/tools/prepare.ts
1102
1129
  /** Discovery pages stay bounded like checkpoint pages. */
1103
1130
  const DISCOVERY_ITEM_LIMIT = 8;
1131
+ const encodeCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
1132
+ /**
1133
+ * The items discovery lists for the CURRENT work: under a v5 boundary that is
1134
+ * the current unit's closure plus its required descendants (the same scope a
1135
+ * v2 certificate answers for, prohibitions included because a standing
1136
+ * constraint is never finished work) plus every pre-v5 obligation, which keeps
1137
+ * their birth rules and must never be silently dropped. A legacy session lists
1138
+ * the whole session. Switched-away sibling units keep their own history and
1139
+ * are reached by item ID, not re-listed here (0.6.1, W060-03).
1140
+ */
1141
+ function discoveryItemIds(p) {
1142
+ 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);
1144
+ const closureUnits = new Set([...p.currentUnitId !== void 0 ? [p.currentUnitId, ...unitDescendantIds(p, p.currentUnitId)] : []]);
1145
+ return pending.filter((item) => item.unitId === void 0 || item.unitId !== void 0 && closureUnits.has(item.unitId)).map((item) => item.id);
1146
+ }
1104
1147
  /**
1105
1148
  * Thin READ-ONLY preparation surface (v0.5/0.6): before any stateful action it
1106
1149
  * reports the supported command shape, the required resolution/effect/state
@@ -1113,7 +1156,7 @@ const DISCOVERY_ITEM_LIMIT = 8;
1113
1156
  function createPrepareTool(options) {
1114
1157
  return defineTool({
1115
1158
  name: "context_guard_prepare",
1116
- description: "Read-only pre-action preparation: report the supported command shape, required resolution/effect/state evidence order, existing references, and exact missing target fields for one contract item. Omit item_id to list current open items with their IDs. Performs no action and grants no authority.",
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.",
1117
1160
  parameters: {
1118
1161
  item_id: { type: "string" },
1119
1162
  item_revision: { type: "number" },
@@ -1122,7 +1165,8 @@ function createPrepareTool(options) {
1122
1165
  type: "object",
1123
1166
  additionalProperties: true
1124
1167
  },
1125
- planned_operation: { type: "string" }
1168
+ planned_operation: { type: "string" },
1169
+ page_cursor: { type: "string" }
1126
1170
  },
1127
1171
  output: {
1128
1172
  schema: {
@@ -1154,14 +1198,44 @@ function createPrepareTool(options) {
1154
1198
  reason_code: "guard_unavailable"
1155
1199
  };
1156
1200
  if (args.item_id === void 0) {
1157
- const open = [...p.items.values()].filter((item$1) => item$1.status === "pending").sort((a, b) => a.revision - b.revision || a.id.localeCompare(b.id));
1201
+ const filter = args.semantic_action ?? null;
1202
+ const invalidCursor = (reason_code, note) => ({
1203
+ status: "rejected",
1204
+ reason_code,
1205
+ mode: "discovery",
1206
+ contract_revision: p.contractRevision,
1207
+ ...note !== void 0 ? { note } : { note: "Re-run discovery without page_cursor to list from the first page." }
1208
+ });
1209
+ let startAfter;
1210
+ if (args.page_cursor !== void 0) {
1211
+ let parsed;
1212
+ try {
1213
+ if (args.page_cursor.length <= 1024) {
1214
+ 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;
1216
+ }
1217
+ } catch {
1218
+ parsed = void 0;
1219
+ }
1220
+ if (!parsed) return invalidCursor("discovery_cursor_malformed");
1221
+ 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.`);
1222
+ if ((parsed.f ?? null) !== (filter ?? null)) return invalidCursor("discovery_cursor_filter_mismatch");
1223
+ startAfter = parsed.k;
1224
+ }
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;
1227
+ 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
+ const page = eligible.slice(startIndex, startIndex + DISCOVERY_ITEM_LIMIT);
1229
+ const hasMore = startIndex + page.length < eligible.length;
1158
1230
  return {
1159
1231
  status: "prepared",
1160
1232
  mode: "discovery",
1161
1233
  durability: p.durabilityWatermark,
1162
1234
  contract_revision: p.contractRevision,
1163
- total_open: open.length,
1164
- items: open.slice(0, DISCOVERY_ITEM_LIMIT).map((item$1) => {
1235
+ total_open: eligible.length,
1236
+ listed: page.length,
1237
+ has_more: hasMore,
1238
+ items: page.map((item$1) => {
1165
1239
  const diagnosis$1 = deriveItemDiagnosis(p, item$1);
1166
1240
  return {
1167
1241
  id: item$1.id,
@@ -1173,7 +1247,14 @@ function createPrepareTool(options) {
1173
1247
  text: item$1.normalizedText
1174
1248
  };
1175
1249
  }),
1176
- note: "Re-run with one item_id to prepare that item. Preparation performs no action."
1250
+ ...hasMore ? { next_cursor: encodeCursor({
1251
+ v: 1,
1252
+ r: p.contractRevision,
1253
+ f: filter,
1254
+ k: [page[page.length - 1].revision, page[page.length - 1].id]
1255
+ }) } : {},
1256
+ ...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."
1177
1258
  };
1178
1259
  }
1179
1260
  const item = p.items.get(args.item_id ?? "");
@@ -1200,11 +1281,11 @@ function createPrepareTool(options) {
1200
1281
  resolved_target: evidence.resolvedTarget,
1201
1282
  tool_result_seq: evidence.toolResultSeq
1202
1283
  }));
1203
- const requiredOrder = manifestEntry?.stateful ? [
1284
+ const requiredOrder = plannedAction && isStatefulAction(plannedAction) ? [
1204
1285
  "resolution (prestate facts from a trusted read)",
1205
1286
  "effect (the exact planned change)",
1206
1287
  "state (independent post-state readback)"
1207
- ] : ["state (matching durable evidence for the requested verification)"];
1288
+ ] : ["effect (one matching durable verification fact)"];
1208
1289
  const recipe = plannedAction && isStatefulAction(plannedAction) ? actionPreparation(plannedAction) : void 0;
1209
1290
  const missingTargetFields = recipe ? recipe.selector_fields.filter((key) => !(item.requestedTarget?.[key] !== void 0 || args.requested_target?.[key] !== void 0)) : [];
1210
1291
  const capability = plannedAction && options.hostCapability ? options.hostCapability(plannedAction) : void 0;
@@ -1243,6 +1324,145 @@ function createPrepareTool(options) {
1243
1324
  });
1244
1325
  }
1245
1326
 
1327
+ //#endregion
1328
+ //#region src/tools/interpret.ts
1329
+ function parsePartition(args, extent) {
1330
+ const read = (key) => {
1331
+ const raw = args[key];
1332
+ if (raw === void 0) return void 0;
1333
+ if (!Array.isArray(raw)) return void 0;
1334
+ const spans = [];
1335
+ for (const entry of raw) {
1336
+ const record$1 = entry;
1337
+ const start = record$1?.start;
1338
+ const end = record$1?.end;
1339
+ if (typeof start !== "number" || !Number.isSafeInteger(start) || typeof end !== "number" || !Number.isSafeInteger(end) || start >= end) return void 0;
1340
+ spans.push({
1341
+ start,
1342
+ end
1343
+ });
1344
+ }
1345
+ return spans;
1346
+ };
1347
+ const information = read("information_spans");
1348
+ const unknown = read("unknown_spans");
1349
+ if (information === void 0 || unknown === void 0) return { error: "interpretation_partition_required" };
1350
+ if (information.length === 0) return { error: "interpretation_partition_required" };
1351
+ const all = [...information, ...unknown];
1352
+ for (const span of all) if (span.start < extent.start || span.end > extent.end) return { error: "interpretation_span_outside_input" };
1353
+ const ordered = [...all].sort((left, right) => left.start - right.start || left.end - right.end);
1354
+ for (let index = 1; index < ordered.length; index += 1) if (ordered[index].start < ordered[index - 1].end) return { error: "interpretation_spans_overlap" };
1355
+ return {
1356
+ information,
1357
+ unknown
1358
+ };
1359
+ }
1360
+ /** The byte extent that covers every source span of one item. */
1361
+ function itemExtent(spans) {
1362
+ return {
1363
+ start: Math.min(...spans.map((span) => span.start)),
1364
+ end: Math.max(...spans.map((span) => span.end))
1365
+ };
1366
+ }
1367
+ function createInterpretTool(options) {
1368
+ return defineTool({
1369
+ name: "context_guard_interpret",
1370
+ description: "Record the interpretation of one unresolved obligation: pass the item ID from context_guard_prepare plus the partition of its input spans you read as information (information_spans) and the sub-spans you could not resolve (unknown_spans); for an attached asset, the partition is unnecessary. Contract bookkeeping only — performs no action, grants no authority. Information sub-spans close when this turn's host-confirmed final answer is delivered; unknown sub-spans remain pending obligations. Correctness is never certified.",
1371
+ parameters: {
1372
+ item_id: {
1373
+ type: "string",
1374
+ required: true
1375
+ },
1376
+ information_spans: {
1377
+ type: "array",
1378
+ items: {
1379
+ type: "object",
1380
+ additionalProperties: true
1381
+ }
1382
+ },
1383
+ unknown_spans: {
1384
+ type: "array",
1385
+ items: {
1386
+ type: "object",
1387
+ additionalProperties: true
1388
+ }
1389
+ }
1390
+ },
1391
+ output: {
1392
+ schema: {
1393
+ type: "object",
1394
+ additionalProperties: true
1395
+ },
1396
+ render: (_args, value) => [{
1397
+ type: "text",
1398
+ text: JSON.stringify(value)
1399
+ }]
1400
+ },
1401
+ async execute(rawArgs) {
1402
+ const args = rawArgs;
1403
+ const reject = (reason_code) => ({
1404
+ status: "rejected",
1405
+ reason_code
1406
+ });
1407
+ if (options.refreshProjection) {
1408
+ let durable = false;
1409
+ try {
1410
+ durable = await options.refreshProjection() === true;
1411
+ } catch {
1412
+ durable = false;
1413
+ }
1414
+ if (!durable) return {
1415
+ status: "unknown",
1416
+ reason_code: "projection_durability_unavailable"
1417
+ };
1418
+ }
1419
+ const p = options.getProjection();
1420
+ if (!p || !p.enabled || p.integrity !== "valid") return reject("guard_unavailable");
1421
+ const itemId = typeof args.item_id === "string" ? args.item_id.trim() : "";
1422
+ if (!itemId) return reject("item_not_found");
1423
+ const item = p.items.get(itemId);
1424
+ if (!item) return reject("item_not_found");
1425
+ if (item.status !== "pending") return reject("item_not_pending");
1426
+ if (!item.asset && item.authorityDisposition !== "unresolved") return reject("not_interpretable");
1427
+ if (item.asset) return {
1428
+ status: "recorded",
1429
+ item_id: item.id,
1430
+ item_revision: item.revision,
1431
+ kind: "asset",
1432
+ asset: {
1433
+ message_seq: item.asset.messageSeq,
1434
+ part_index: item.asset.partIndex,
1435
+ media_sha256: item.asset.mediaSha256
1436
+ },
1437
+ note: "Interpretation recorded for this asset obligation. It closes when the host-confirmed final answer of this interpreting turn is delivered; this record never certifies the interpretation's correctness and never authorizes or proves any execution."
1438
+ };
1439
+ if (!item.spans || item.spans.length === 0) return reject("item_spans_unavailable");
1440
+ const partition = parsePartition(args, itemExtent(item.spans));
1441
+ if ("error" in partition) return reject(partition.error);
1442
+ return {
1443
+ status: "recorded",
1444
+ item_id: item.id,
1445
+ item_revision: item.revision,
1446
+ kind: "clause",
1447
+ spans: item.spans.map((span) => ({
1448
+ part_index: span.partIndex,
1449
+ start: span.start,
1450
+ end: span.end
1451
+ })),
1452
+ information_spans: partition.information.map((span) => ({
1453
+ start: span.start,
1454
+ end: span.end
1455
+ })),
1456
+ unknown_spans: partition.unknown.map((span) => ({
1457
+ start: span.start,
1458
+ end: span.end
1459
+ })),
1460
+ note: "Interpretation partition recorded for this unresolved clause: information sub-spans close when the host-confirmed final answer of this interpreting turn is delivered; every unknown sub-span remains a pending obligation and must still be resolved or performed. This record never certifies correctness and never authorizes any execution."
1461
+ };
1462
+ }
1463
+ });
1464
+ }
1465
+
1246
1466
  //#endregion
1247
1467
  //#region src/tools/evidence.ts
1248
1468
  const execFileAsync = promisify(execFile);
@@ -1836,7 +2056,7 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1836
2056
  if (action === "install" || action === "apply") {
1837
2057
  const tgzPath = requireString(resolution.commandManifest, "tgz_path");
1838
2058
  const identity = tgzPath ? await tgzIdentity(tgzPath) : void 0;
1839
- if (!executableIdentity$1 || !tgzPath || !identity || identity.name !== target.package_id || identity.version !== target.version || identity.integrity !== target.integrity_digest || roots.profile?.name !== target.profile) return "unavailable";
2059
+ if (!executableIdentity$1 || !tgzPath || !identity || identity.name !== target.package_id || identity.version !== target.version || identity.integrity !== target.integrity_digest || roots.profile?.name !== target.profile) return { status: "unavailable" };
1840
2060
  await runCommand(roots, executableIdentity$1, [
1841
2061
  "plugin",
1842
2062
  "--profile",
@@ -1844,13 +2064,13 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1844
2064
  "add",
1845
2065
  `file:${tgzPath}`
1846
2066
  ], void 0, signal);
1847
- return "completed";
2067
+ return { status: "completed" };
1848
2068
  }
1849
2069
  if (action === "publish") {
1850
2070
  const tgzPath = requireString(resolution.commandManifest, "tgz_path");
1851
2071
  const identity = tgzPath ? await tgzIdentity(tgzPath) : void 0;
1852
2072
  const registry = typeof target.registry === "string" ? canonicalRegistryBase(target.registry, { allowLoopbackHttp: roots.allowLoopbackHttpRegistry }) : void 0;
1853
- if (!executableIdentity$1 || !tgzPath || !identity || identity.name !== target.artifact_id || identity.version !== target.version || identity.integrity !== target.integrity_digest || !registry || registry !== target.registry) return "unavailable";
2073
+ if (!executableIdentity$1 || !tgzPath || !identity || identity.name !== target.artifact_id || identity.version !== target.version || identity.integrity !== target.integrity_digest || !registry || registry !== target.registry) return { status: "unavailable" };
1854
2074
  await runCommand(roots, executableIdentity$1, [
1855
2075
  "publish",
1856
2076
  tgzPath,
@@ -1858,19 +2078,19 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1858
2078
  registry,
1859
2079
  "--ignore-scripts"
1860
2080
  ], void 0, signal);
1861
- return "completed";
2081
+ return { status: "completed" };
1862
2082
  }
1863
2083
  if (action === "restart") {
1864
2084
  const capabilities = await marketCapabilities(roots, signal);
1865
- if (!capabilities || !roots.marketOrigin || !resolutionCallId || !agent) return "unavailable";
1866
- if (!sameMarketProvider(target.pre_generation, capabilities.generation)) return "unavailable";
1867
- if (capabilities.generation !== target.pre_generation) return restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target) ? "completed" : "unavailable";
1868
- if (restartIntent(snapshotSessionEvents(agent.session), resolutionCallId, target)) return "handoff_pending";
2085
+ if (!capabilities || !roots.marketOrigin || !resolutionCallId || !agent) return { status: "unavailable" };
2086
+ 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" };
1869
2089
  if (!roots.persistRestartIntent || !await roots.persistRestartIntent(agent, {
1870
2090
  resolutionCallId,
1871
2091
  serviceId: String(target.service_id),
1872
2092
  preGeneration: String(target.pre_generation)
1873
- })) return "unavailable";
2093
+ })) return { status: "unavailable" };
1874
2094
  const response = await (roots.fetcher ?? fetch)(`${roots.marketOrigin}/dsh-market/api/v1/restart`, {
1875
2095
  method: "POST",
1876
2096
  signal,
@@ -1882,21 +2102,25 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1882
2102
  },
1883
2103
  body: "{}"
1884
2104
  });
1885
- if (!response.ok) return "unavailable";
1886
- return record(await response.json())?.schema === MARKET_SCHEMA ? "handoff_pending" : "unavailable";
2105
+ if (!response.ok) return { status: "unavailable" };
2106
+ return record(await response.json())?.schema === MARKET_SCHEMA ? { status: "handoff_pending" } : { status: "unavailable" };
1887
2107
  }
1888
2108
  if (action === "commit" || action === "push" || action === "pull" || action === "fetch") {
1889
2109
  const binding = resolution.gitBinding;
1890
2110
  const repository = requireString(resolution.target, "repository");
1891
- if (!executableIdentity$1 || !binding || !repository) return "unavailable";
2111
+ if (!executableIdentity$1 || !binding || !repository) return { status: "unavailable" };
1892
2112
  const targetIdentity = {
1893
2113
  repository,
1894
2114
  ...typeof resolution.target.remote === "string" ? { remote: resolution.target.remote } : {},
1895
2115
  ...typeof resolution.target.refspec === "string" ? { refspec: resolution.target.refspec } : {}
1896
2116
  };
1897
2117
  const current = await gitPrestate(binding.manifest, repository, signal, executableIdentity$1.realpath);
1898
- if (!current) return "unavailable";
1899
- if ((await executeRevalidatedGitEffect(binding.envelope, binding.manifest, targetIdentity, current, async (_file, argv, workingDirectory) => runCommand(roots, executableIdentity$1, argv, workingDirectory, signal))).status !== "executed") return "unavailable";
2118
+ if (!current) return { status: "unavailable" };
2119
+ const executed = await executeRevalidatedGitEffect(binding.envelope, binding.manifest, targetIdentity, current, async (_file, argv, workingDirectory) => runCommand(roots, executableIdentity$1, argv, workingDirectory, signal));
2120
+ if (executed.status !== "executed") return {
2121
+ status: "unavailable",
2122
+ reasonCode: executed.reasonCode
2123
+ };
1900
2124
  if (action === "commit") {
1901
2125
  const commit = verifiedLinearCommitReadback(await gitBytes(repository, [
1902
2126
  "rev-list",
@@ -1911,10 +2135,10 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1911
2135
  "-z",
1912
2136
  commit.postHeadOid
1913
2137
  ], signal, executableIdentity$1.realpath)) : void 0;
1914
- if (!commit || postTree !== resolution.target.change_set_digest) return "unavailable";
2138
+ if (!commit || postTree !== resolution.target.change_set_digest) return { status: "unavailable" };
1915
2139
  } else if (action === "push") {
1916
2140
  const remoteOid = binding.manifest.remote && binding.manifest.destinationRef ? await exactRemoteOid(repository, binding.manifest.remote, binding.manifest.destinationRef, signal, executableIdentity$1.realpath) : void 0;
1917
- if (!remoteOid || remoteOid !== resolution.target.local_oid) return "unavailable";
2141
+ if (!remoteOid || remoteOid !== resolution.target.local_oid) return { status: "unavailable" };
1918
2142
  } else {
1919
2143
  const upstream = String(resolution.target.upstream_oid ?? "");
1920
2144
  const trackingRef = binding.manifest.action === "fetch" ? binding.manifest.trackingRef : binding.manifest.remote && binding.manifest.sourceRef ? `refs/remotes/${binding.manifest.remote}/${binding.manifest.sourceRef.slice(11)}` : void 0;
@@ -1923,13 +2147,13 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
1923
2147
  "--verify",
1924
2148
  trackingRef
1925
2149
  ], signal, executableIdentity$1.realpath)) : void 0;
1926
- if (!tracking || tracking !== upstream) return "unavailable";
1927
- if (action === "pull" && oid(await git(repository, ["rev-parse", "HEAD"], signal, executableIdentity$1.realpath)) !== upstream) return "unavailable";
1928
- if (action === "fetch" && oid(await git(repository, ["rev-parse", "HEAD"], signal, executableIdentity$1.realpath)) !== resolution.target.pre_head_oid) return "unavailable";
2150
+ if (!tracking || tracking !== upstream) return { status: "unavailable" };
2151
+ if (action === "pull" && oid(await git(repository, ["rev-parse", "HEAD"], signal, executableIdentity$1.realpath)) !== upstream) return { status: "unavailable" };
2152
+ if (action === "fetch" && oid(await git(repository, ["rev-parse", "HEAD"], signal, executableIdentity$1.realpath)) !== resolution.target.pre_head_oid) return { status: "unavailable" };
1929
2153
  }
1930
- return "completed";
2154
+ return { status: "completed" };
1931
2155
  }
1932
- return "unavailable";
2156
+ return { status: "unavailable" };
1933
2157
  }
1934
2158
  async function gitBytes(repository, args, signal, file = "git") {
1935
2159
  const { stdout } = await execFileAsync(file, args, {
@@ -2575,15 +2799,15 @@ function createActionTool(options = {}) {
2575
2799
  releaseContractId = decision.contractId;
2576
2800
  }
2577
2801
  try {
2578
- const status = await executeGuardAction(action, resolution, roots, exec.signal, currentExecutable, args.resolution_call_id, agent);
2802
+ const outcome = await executeGuardAction(action, resolution, roots, exec.signal, currentExecutable, args.resolution_call_id, agent);
2579
2803
  if (releaseOperation && releaseGranted && roots.releaseSettle) {
2580
- const readback$1 = status === "completed" ? await publishReadback(resolution.target, roots, exec.signal) : void 0;
2804
+ const readback$1 = outcome.status === "completed" ? await publishReadback(resolution.target, roots, exec.signal) : void 0;
2581
2805
  await roots.releaseSettle({
2582
2806
  agent,
2583
2807
  operation: releaseOperation,
2584
2808
  callId: args.resolution_call_id,
2585
2809
  ...releaseContractId !== void 0 ? { contractId: releaseContractId } : {},
2586
- effect: status === "completed" ? "completed" : status === "unavailable" ? "not_effected" : "unknown",
2810
+ effect: outcome.status === "completed" ? "completed" : outcome.status === "unavailable" ? "not_effected" : "unknown",
2587
2811
  readback: readback$1 === void 0 ? "unavailable" : {
2588
2812
  kind: "npm_integrity",
2589
2813
  identity: readback$1
@@ -2591,8 +2815,8 @@ function createActionTool(options = {}) {
2591
2815
  });
2592
2816
  }
2593
2817
  return {
2594
- status,
2595
- reason_code: status === "completed" ? "action_completed" : status === "handoff_pending" ? "restart_handoff_pending" : "action_execution_failed",
2818
+ status: outcome.status,
2819
+ reason_code: outcome.status === "completed" ? "action_completed" : outcome.status === "handoff_pending" ? "restart_handoff_pending" : outcome.reasonCode === "effect_already_applied" ? "action_already_applied" : "action_execution_failed",
2596
2820
  ...identity
2597
2821
  };
2598
2822
  } catch {
@@ -3321,13 +3545,27 @@ function createContextGuardCommand(projectionFor, setEnabled, clearContract, lif
3321
3545
  const passed = [...projection.items.values()].filter((item) => item.status === "passed").length;
3322
3546
  let certifiable_missing_evidence = 0;
3323
3547
  let unsupported = 0;
3548
+ let input_required = 0;
3549
+ let capability_limited = 0;
3324
3550
  const reason_classes = {};
3325
3551
  for (const item of projection.items.values()) {
3326
3552
  if (item.status !== "pending") continue;
3327
3553
  const diagnosis = deriveItemDiagnosis(projection, item);
3328
3554
  reason_classes[diagnosis.reason_class] = (reason_classes[diagnosis.reason_class] ?? 0) + 1;
3329
- if (diagnosis.repairability === "agent_repairable") certifiable_missing_evidence += 1;
3330
- else if (diagnosis.certification === "unsupported") unsupported += 1;
3555
+ switch (diagnosis.capability.remedy) {
3556
+ case "collect_evidence":
3557
+ certifiable_missing_evidence += 1;
3558
+ break;
3559
+ case "supply_target":
3560
+ case "await_root_input":
3561
+ input_required += 1;
3562
+ break;
3563
+ case "fresh_root_instruction":
3564
+ case "restore_host":
3565
+ capability_limited += 1;
3566
+ break;
3567
+ default: unsupported += 1;
3568
+ }
3331
3569
  }
3332
3570
  const migration = migrationReport(projection);
3333
3571
  const response = {
@@ -3341,6 +3579,8 @@ function createContextGuardCommand(projectionFor, setEnabled, clearContract, lif
3341
3579
  diagnosis: {
3342
3580
  certified: passed,
3343
3581
  certifiable_missing_evidence,
3582
+ input_required,
3583
+ capability_limited,
3344
3584
  unsupported,
3345
3585
  reason_classes
3346
3586
  },
@@ -4927,6 +5167,15 @@ function apply(ctx, rawConfig = {}, seams = {}) {
4927
5167
  return durable;
4928
5168
  }
4929
5169
  }));
5170
+ agent.ctx.tools.register(createInterpretTool({
5171
+ getProjection: () => runtime.projection,
5172
+ refreshProjection: async () => {
5173
+ const durable = await ctx.sessions.flush(agent.session);
5174
+ runtime.setDurability(durable);
5175
+ runtime.sync();
5176
+ return durable;
5177
+ }
5178
+ }));
4930
5179
  agent.ctx.tools.register(createReleaseTool({
4931
5180
  getProjection: () => runtime.projection,
4932
5181
  fetcher: evidenceOptions.fetcher,
@@ -4958,7 +5207,8 @@ function apply(ctx, rawConfig = {}, seams = {}) {
4958
5207
  enabled: runtime.projection.enabled,
4959
5208
  boundaryV5Present: runtime.protocolV5Present,
4960
5209
  boundaryPresent: runtime.protocolV4Present,
4961
- delegated
5210
+ delegated,
5211
+ policy: runtime.projection.policy
4962
5212
  }, claimedBatchHasRealRootInput(decision.messages));
4963
5213
  if (firstStep) {
4964
5214
  injected.push(pluginNoticeMessage(firstStep.boundary, "Context Guard recorded a replay version boundary"));
@@ -5117,4 +5367,4 @@ function normalizeGoalState(value) {
5117
5367
  }
5118
5368
 
5119
5369
  //#endregion
5120
- 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, COMMAND_SURFACE_MANIFEST, CONFIRM_LINE_PATTERN, CONTROL_RECORD_PREFIX, Config, DEFAULT_DELEGATION_TOOL_NAMES, DEFAULT_HOST_LOCK, DEFAULT_RECOVERY_CHAR_BUDGET, 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, apply, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, captureClause, captureItem, certifyCheckpoint, claimedBatchHasRealRootInput, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, 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, 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, previewFirstStepInjection, progressFingerprint, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualifyBoundary, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, relevantEvidence, 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 };
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 };
@@ -43,6 +43,8 @@ Recovery packets keep the existing content-dedup and ride the next entered step.
43
43
 
44
44
  `deriveItemDiagnosis` is the single pure judge shared by checkpoint, recovery, the rebind item query, `context_guard_prepare`, and `/context-guard status`. Per item it reports a task kind (`inquiry`/`action`/`constraint`/…), certification support (`unsupported`/`needs_target`/`needs_evidence`/`unavailable`/`supported`), repairability (agent-repairable, needs user input, unsupported, historical gap, none), the exact missing target fields and evidence facets, and one concrete next action with a resume condition and a stable attempt fingerprint. Inquiries stay captured obligations whose honest next step is to deliver the answer; they are never prescribed a rebind. An effect recorded without its resolution prestate is a historical gap: read back observed state, never re-execute to mint evidence.
45
45
 
46
+ 0.6.2 adds the shared capability projection beside that verdict (`src/domain/capability-semantics.ts`). Every lane declares one gap kind — unknown interpretation, missing target, missing adapter, legacy migration, missing historical pre-evidence, unattributable operation, pending condition, pending delivery, unavailable host, or standing constraint — and exactly one reachable remedy. Every consumer reads that projection instead of inferring a root cause from one enum, which is what stops a capability this build lacks from being reported as a user-authorization gap. Shell facts additionally carry a layered reading (`processFacts`): the host tool's own return, the console's declared exit status or `unknown`, how far the effect was attributed to this obligation's operation, and the resulting business outcome. Those fields are derived at replay, are excluded from every digest and certificate domain, and never rewrite a historical `outcome` or `parseStatus`.
47
+
46
48
  `context_guard_prepare` is read-only. Before a stateful action it renders the supported command shape from the same audited parser the executor uses, the required resolution/effect/state order, reusable evidence references, the host capability verdict, and the exact missing target fields. It performs no action and never turns a guessed default into user authority.
47
49
 
48
50
  A log-derived retry ledger keys each rejected rebind attempt by its stable inputs and outcome. An identical second attempt returns `unchanged` with the resume condition instead of a fresh rejection; new related evidence, a new root instruction, or a changed target produces a new key and re-opens evaluation.