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/CHANGELOG.md +44 -1
- package/CHANGELOG.zh-CN.md +29 -1
- package/README.md +52 -9
- package/README.zh-CN.md +24 -8
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.js +2 -2
- package/dist/{domain-COehX7MB.js → domain-BtR3J5aL.js} +914 -95
- package/dist/{index-BJPVGdg9.d.ts → index-CZSt3D0G.d.ts} +277 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +293 -43
- package/docs/ARCHITECTURE.md +2 -0
- package/docs/CROSS_END_RESULT_CONTRACT.md +60 -0
- package/docs/DEVELOPMENT_PLAN_0_6_2.md +86 -0
- package/docs/LOCAL_ACCEPTANCE.md +153 -1
- package/docs/RELEASE_PLAN_0_6_2.md +41 -0
- package/docs/SEMANTIC_COMPATIBILITY.md +15 -0
- package/package.json +2 -2
- package/docs/NEXT_VERSION_REPAIR_NOTES.md +0 -81
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
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) <=
|
|
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
|
-
|
|
325
|
-
|
|
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
|
|
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
|
|
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:
|
|
1164
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
] : ["
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
3330
|
-
|
|
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 };
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -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.
|