dsh-completion-guard 0.6.2 → 0.6.3
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 +65 -0
- package/CHANGELOG.zh-CN.md +19 -0
- package/README.md +52 -8
- package/README.zh-CN.md +13 -5
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.js +2 -2
- package/dist/{domain-BtR3J5aL.js → domain-BUA1lLjs.js} +6492 -4484
- package/dist/{index-CZSt3D0G.d.ts → index-CfEiC4bb.d.ts} +287 -14
- package/dist/index.d.ts +2 -2
- package/dist/index.js +220 -16
- package/docs/ARCHITECTURE.md +4 -0
- package/docs/CONTRACT_REVISION_0_6_3.md +136 -0
- package/docs/DEVELOPMENT_HANDOFF_0_6_3.json +65 -0
- package/docs/DEVELOPMENT_PLAN_0_6_3.md +103 -0
- package/docs/EXECUTE_0_6_3_PROMPT.md +62 -0
- package/docs/LOCAL_ACCEPTANCE.md +889 -0
- package/docs/REVIEW_0_6_2_CORE_ALIGNMENT.md +87 -0
- package/docs/SEMANTIC_COMPATIBILITY.md +49 -1
- package/docs/upstream-deltas.json +67 -11
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as evidenceFromPersistedToolResult, $n as proposeRebind, $r as isRestatement, $t as createProofManifestV2, A as lifecyclePhase, Ai as requestedTargetMatchesResolved, An as NO_PROGRESS_TURNS_BEFORE_STOP, Ar as canonicalRegistryBase, At as SUPPORTED_HOST_RANGE, B as RELEASE_OPERATIONS, Bi as sanitizeClauseText, Bn as progressFingerprint, Br as clauseIsProtected, Bt as authorityCaptureCounts, C as gitCommandMatchesTarget, Ci as STOP_PROTOCOL_VERSION_V2, Cn as renderRecoveryPacket, Cr as classifyClause, Ct as evaluateHostCapability, D as FIRST_STEP_GUIDANCE, Di as isStatefulAction, Dn as isVerifyingCapability, Dr as extractOperation, Dt as selectHostCohort, E as verifiedLinearCommitReadback, Ei as boundedArtifactChoiceMatches, En as evidenceMatchesItem, Er as extractMethod, Et as hostVersionFromPackages, F as PROTOCOL_V4_NOTICE, Fi as COMMAND_SURFACE_MANIFEST, Fn as isRootPauseRequest, Fr as LEGACY_QUALIFICATION, Ft as satisfiesSupportedHostRange, G as inFlightReservation, Gn as unitDescendantIds, Gr as interpretClause, Gt as PROOF_KINDS_V2, H as RELEASE_RESERVATION_PREFIX, Hi as sha256, Hn as hasCurrentCertificate, Hr as governedClauseRestrictsExecution, Ht as certifyCheckpoint, I as PROTOCOL_V5_NOTICE, Ii as validateManifest, In as isWholeTaskCompletionClaim, Ir as actionVerbMatches, It as RC015_RC2_HOST_PACKAGES, J as releaseContractFor, Jn as isCurrentAcceptedBoundary, Jr as isExecutableItem, Jt as PROOF_PROTOCOL_VERSION_V2, K as normalizeReleaseContract, Kn as availableBoundaryQualifications, Kr as interpretMessage, Kt as PROOF_MANIFEST_DOMAIN_V2, L as applyUpgradeEligibility, Li as canonicalizePath, Ln as latestAssistantText, Lr as clarifiedSpanOf, Lt as RC015_HOST_PACKAGES, M as CAPTURE_V042_NOTICE, Mi as semanticActionFromText, Mn as decideTurnBoundary, Mr as classifyTaskIntent, Mt as compareHostVersions, N as DEFAULT_DELEGATION_TOOL_NAMES, Ni as validateActionManifest, Nn as decideTurnStopping, Nr as classifyUserInteraction, Nt as evaluateMinimumHostVersion, O as claimedBatchHasRealRootInput, Oi as requestedIdentityKey, On as CONTROL_RECORD_PREFIX, Or as isInformationalMessage, Ot as LATEST_SUPPORTED_HOST_VERSION, P as PROTOCOL_V3_NOTICE, Pi as validateActionTarget, Pn as decisionBoundaryKey, Pr as GRANTED_QUALIFICATION, Pt as parseHostVersion, Q as supersedeItem, Qn as confirmRebind, Qr as isQuestionScopeNeedingReview, Qt as createProofManifest, R as deriveProjection, Ri as digestStrings, Rn as latestRootInstruction, Rr as clauseAsksOwnQuestion, Rt as RC1_HOST_PACKAGES, S as executeRevalidatedGitEffect, Si as STOP_PROTOCOL_VERSION, Sn as recoveryDigest, Sr as captureItem, St as evaluateExternalWaitCapability, T as revalidateGitPrestate, Ti as actionCompatible, Tn as evidenceCoverage, Tr as extractArtifactPaths, Tt as evaluateToolSurfaceCapability, U as RELEASE_SETTLEMENT_PREFIX, Un as certifiableOpenItems, Ur as hasOrderedCoordination, Ut as PROOF_CAPABILITY_MATRIX, V as RELEASE_OPERATION_SURFACES, Vi as sanitizeUrl, Vn as goalCompletionDenial, Vr as explanationHasActionResidue, Vt as segmentAuthorityBlocks, W as contractById, Wn as certificateClosure, Wr as hasQuestionScope, Wt as PROOF_KINDS, X as releasePreEffectDecision, Xn as currentContractDigest, Xr as isInformationalFragment, Xt as bindProofV2ToProjection, Y as releaseCoverage, Yn as qualifyBoundary, Yr as isExplanationScope, Yt as bindProofToProjection, Z as reservationFor, Zn as createProjection, Zr as isOpenObligation, Zt as canonicalProjection, _ as GIT_COMMAND_MANIFEST_IDS, _i as BOUNDED_ARTIFACT_TYPES, _n as MIN_RECOVERY_CHAR_BUDGET, _r as capabilityFactOf, _t as HOST_CAPABILITY_PACKAGE_GROUPS, a as injectActiveProfileHostLock, ai as namedActions, an as proofOperationMatches, ar as CONFIRM_LINE_PATTERN, at as isRunExecutable, b as commitTreeSnapshotDigest, bi as SEMANTIC_ACTIONS, bn as closingHint, br as removalIsPartiallyKnown, bt as bindExecutableIdentity, c as packageRowsFromPnpmLock, ci as questionHeadsClause, cn as scopeCoverageDigest, cr as capabilityRemedyPhrase, ct as ACTIVE_HOST_COHORT_ID, d as resolveInstalledHostLock, di as semanticActionOfScope, dn as validateProofManifest, dr as itemDiagnosis, dt as ALPHA2_DSHMARKET_139_HOST_PACKAGES, ei as itemHoldsExecutionAuthority, en as proofCapabilityReport, er as proposeRebindOutcome, et as extractTextContent, f as verifyComposedHostLockDump, fi as splitTextFragments, fn as validateProofManifestV2, fr as relevantEvidence, ft as ALPHA2_HOST_PACKAGES, g as snapshotSessionEvents, gi as ACTION_MANIFEST_VERSION, gn as DEFAULT_RECOVERY_CHAR_BUDGET, gr as capabilityConsequence, gt as GOAL_HOST_PACKAGES, h as SessionApiError, hi as ACTION_MANIFEST, hn as CLEANUP_CONDITION_RULE_SHORT, hr as admissibleForRemoval, ht as EXPECTED_HOST_PACKAGES, i as hostLockRowsFromComposedDump, ii as maskQuotedSpans, in as proofHostSurfacesOf, ir as replayRebindResult, it as canonicalArgvFromCommand, j as previewFirstStepInjection, ji as semanticActionFromCommand, jn as classifyCompletionClaim, jr as npmEscapedPackageName, jt as SUPPORTED_HOST_VERSIONS, k as firstStepGuidance, ki as requestedTargetAuthorizesMutation, kn as NO_PROGRESS_RECORD_PREFIX, kr as segmentClauses, kt as MIN_SUPPORTED_HOST_VERSION, l as readActiveHostGraph, li as reportingHeadGoverns, ln as sessionQuery, lr as deriveItemDiagnosis, lt as ACTIVE_HOST_COHORT_IDS, m as SESSION_EVENT_ENVELOPE_INVALID, mi as verbIsNegated, mn as CLEANUP_CONDITION_RULE_COMPACT, mr as actionHasCertificationPath, mt as DEFAULT_HOST_LOCK, n as combineHostPolicy, ni as legacyQuestionReadingIsInformational, nn as proofDigestV2, nr as rebindAttemptKey, nt as isDeterministicCheck, o as inspectTargetHostGraph, oi as opensWithDirective, on as proofV2Rejection, or as isFrozenV042RebindResponse, ot as parsePwshCommand, p as SESSION_API_UNSUPPORTED, pi as statefulActionsOfScope, pn as CLEANUP_CONDITION_RULE, pr as DEPENDENCY_FREE_ONLY_CONDITION, pt as BASE_HOST_PACKAGES, q as readbackSettlesContract, qn as effectuateBoundary, qr as introducesActionClause, qt as PROOF_PROTOCOL_VERSION, r as hostLockContextFromComposedDump, ri as maskCodeSpans, rn as proofEvidenceConstraints, rr as rebindResponse, rt as withDurability, s as packageRowsFromActiveGraph, si as qualificationOfClause, sn as requiredSubjectsOf, sr as parseConfirmationMessage, st as parseShellCommand, t as HostProfileError, ti as kindOfScope, tn as proofDigest, tr as proposeRebindV042, tt as extractToolSubject, u as resolveActiveProfileHostLock, ui as restatedContentOf, un as sessionQueryV2, ur as evidenceAvailabilityReason, ut as ACTIVE_HOST_LAUNCHER_VERSION, v as GIT_COMMAND_TEMPLATES, vi as CERTIFICATE_VERSION, vn as carriesCleanupCondition, vr as partialFailureOf, vt as HOST_COHORTS, w as parseGitCommandManifest, wi as SUPPORTED_EVIDENCE_ADAPTERS, wn as bindingSatisfies, wr as environmentDefaultRepositoryTarget, wt as evaluateHostLock, x as createGitPrestateEnvelope, xi as STATEFUL_ACTIONS, xn as openItems, xr as captureClause, xt as bindLiveGoalCapability, y as commitIndexSnapshotDigest, yi as CERTIFICATE_VERSION_V2, yn as cleanupConditionFor, yr as removalIsComplete, yt as LEGACY_HOST_COHORTS, z as legacyRecordsNeedingReview, zi as normalizeClause, zn as observeAssistantOutcome, zr as clauseIsGoverned, zt as ALPHA3_HOST_PACKAGES } from "./domain-BUA1lLjs.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";
|
|
@@ -1124,8 +1124,103 @@ function actionPreparation(action) {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
+
//#endregion
|
|
1128
|
+
//#region src/domain/compatibility.ts
|
|
1129
|
+
/** The identity field a caller must supply for this action, when it has one. */
|
|
1130
|
+
function requiredIdentityFieldOf(action) {
|
|
1131
|
+
return requestedIdentityKey(action);
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* The single compatibility judgement. `input.resolvedTarget` is compared with
|
|
1135
|
+
* the item's own requested target using the caller-supplied relation, so this
|
|
1136
|
+
* module never re-implements target identity: the caller passes the same
|
|
1137
|
+
* predicate it would use when authorizing.
|
|
1138
|
+
*/
|
|
1139
|
+
function evaluateCompatibility(input, targetMatches) {
|
|
1140
|
+
const identityField = requiredIdentityFieldOf(input.action);
|
|
1141
|
+
const base = {
|
|
1142
|
+
assumedAction: input.action,
|
|
1143
|
+
...identityField !== void 0 ? { requiredIdentityField: identityField } : {},
|
|
1144
|
+
itemAction: input.itemAction,
|
|
1145
|
+
certifiable: input.adapterSupported === true || !isStatefulAction(input.action)
|
|
1146
|
+
};
|
|
1147
|
+
const incompatible = (reasonCode) => ({
|
|
1148
|
+
...base,
|
|
1149
|
+
status: "incompatible",
|
|
1150
|
+
reasonCodes: [reasonCode],
|
|
1151
|
+
semanticsCompatible: reasonCode !== "action_not_compatible_with_item" && reasonCode !== "rebind_does_not_authorize_action",
|
|
1152
|
+
targetCompatible: reasonCode !== "requested_resolved_target_mismatch"
|
|
1153
|
+
});
|
|
1154
|
+
const blocked = (reasonCode) => ({
|
|
1155
|
+
...base,
|
|
1156
|
+
status: "blocked",
|
|
1157
|
+
reasonCodes: [reasonCode],
|
|
1158
|
+
semanticsCompatible: true,
|
|
1159
|
+
targetCompatible: true
|
|
1160
|
+
});
|
|
1161
|
+
if (input.itemRevision !== void 0 && input.currentRevision !== void 0 && input.itemRevision !== input.currentRevision) return {
|
|
1162
|
+
...blocked("item_revision_mismatch"),
|
|
1163
|
+
certifiable: false
|
|
1164
|
+
};
|
|
1165
|
+
if (input.action !== input.itemAction && !actionCompatible(input.itemAction, input.action)) return incompatible("action_not_compatible_with_item");
|
|
1166
|
+
if (input.reboundFrom && input.originalAuthority?.semanticAction === input.itemAction && input.originalAuthority.semanticAction !== input.action) return incompatible("rebind_does_not_authorize_action");
|
|
1167
|
+
const itemSelectedTarget = input.targetCaptureStatus === "resolved" && input.targetSourceKind !== "environment_default";
|
|
1168
|
+
if (input.action === input.itemAction && input.resolvedTarget !== void 0 && itemSelectedTarget && !input.boundedSelectionAuthorized && !targetMatches(input.requestedTarget, input.resolvedTarget)) return {
|
|
1169
|
+
...incompatible("requested_resolved_target_mismatch"),
|
|
1170
|
+
semanticsCompatible: true,
|
|
1171
|
+
targetCompatible: false
|
|
1172
|
+
};
|
|
1173
|
+
if (input.enabled === false) return blocked("guard_disabled");
|
|
1174
|
+
if (input.integrity !== void 0 && input.integrity !== "valid") return blocked("guard_integrity_unavailable");
|
|
1175
|
+
if (input.hostStatus !== void 0 && input.hostStatus !== "supported") return blocked("host_lock_unavailable");
|
|
1176
|
+
if (input.itemKind === "prohibition") return blocked("prohibition_active");
|
|
1177
|
+
if (input.itemStatus !== void 0 && input.itemStatus !== "pending") return blocked("item_not_pending");
|
|
1178
|
+
if (input.itemKind !== void 0 && input.itemKind !== "requirement") return blocked("item_not_authorizing");
|
|
1179
|
+
if (input.authority !== void 0 && input.authority !== "root_instruction" && input.authority !== "root_adoption") return blocked("root_authority_unavailable");
|
|
1180
|
+
if (input.legacyFlags?.length) return blocked("legacy_rebind_required");
|
|
1181
|
+
if (input.authorityDisposition === "conditional_wait") return blocked("awaiting_root_condition");
|
|
1182
|
+
if (input.waitAuthorization !== void 0) return blocked("awaiting_root_wait");
|
|
1183
|
+
if (input.authorityDisposition === "human_actor") return blocked("human_executor");
|
|
1184
|
+
if (input.targetCaptureStatus !== void 0 && input.targetCaptureStatus !== "resolved") return blocked("target_clarification_required");
|
|
1185
|
+
if (input.targetSourceKind === "environment_default") return blocked("target_environment_default");
|
|
1186
|
+
if (input.resolvedTarget !== void 0 && input.targetAuthorizes === false) return {
|
|
1187
|
+
...blocked("target_not_authorizing"),
|
|
1188
|
+
targetCompatible: false
|
|
1189
|
+
};
|
|
1190
|
+
if (input.conflictingProhibition) return blocked("conflicting_prohibition");
|
|
1191
|
+
if (input.adapterSupported === false && isStatefulAction(input.action)) return blocked("adapter_unavailable");
|
|
1192
|
+
if (input.holdsExecutionAuthority === false) return blocked("item_not_executable");
|
|
1193
|
+
return {
|
|
1194
|
+
...base,
|
|
1195
|
+
status: "compatible",
|
|
1196
|
+
reasonCodes: [],
|
|
1197
|
+
semanticsCompatible: true,
|
|
1198
|
+
targetCompatible: true
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Whether the installed cohort can certify this action at all. Kept separate
|
|
1203
|
+
* from {@link evaluateCompatibility} so a caller never reads a capability gap
|
|
1204
|
+
* as a permission or an interpretation problem.
|
|
1205
|
+
*/
|
|
1206
|
+
function actionHasAdapter(action) {
|
|
1207
|
+
if (!isStatefulAction(action)) return true;
|
|
1208
|
+
return ACTION_MANIFEST.actions[action].evidenceProducer === "supported";
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1127
1211
|
//#endregion
|
|
1128
1212
|
//#region src/tools/prepare.ts
|
|
1213
|
+
/**
|
|
1214
|
+
* Whether a standing prohibition the gate would refuse now covers this
|
|
1215
|
+
* hypothesis. It mirrors `authorizeMutationFromProjection`'s own check: a
|
|
1216
|
+
* pending, root-authorized, non-legacy prohibition on the same action whose
|
|
1217
|
+
* declared identity matches the target this preparation is about.
|
|
1218
|
+
*/
|
|
1219
|
+
function conflictsWithProhibition(projection, action, item) {
|
|
1220
|
+
const resolved = item.requestedTarget;
|
|
1221
|
+
if (resolved === void 0) return false;
|
|
1222
|
+
return [...projection.items.values()].some((candidate) => candidate.status === "pending" && candidate.kind === "prohibition" && (candidate.authority === "root_instruction" || candidate.authority === "root_adoption") && !candidate.legacyFlags?.length && candidate.semanticAction === action && requestedTargetMatchesResolved(action, candidate.requestedTarget, resolved));
|
|
1223
|
+
}
|
|
1129
1224
|
/** Discovery pages stay bounded like checkpoint pages. */
|
|
1130
1225
|
const DISCOVERY_ITEM_LIMIT = 8;
|
|
1131
1226
|
const encodeCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
@@ -1268,12 +1363,76 @@ function createPrepareTool(options) {
|
|
|
1268
1363
|
item_revision: item.revision
|
|
1269
1364
|
};
|
|
1270
1365
|
const diagnosis = deriveItemDiagnosis(p, item);
|
|
1366
|
+
const itemAction = item.semanticAction ?? "generic_run";
|
|
1271
1367
|
const plannedAction = args.semantic_action ?? item.semanticAction;
|
|
1272
1368
|
const manifestEntry = plannedAction ? ACTION_MANIFEST.actions[plannedAction] : void 0;
|
|
1273
1369
|
if (plannedAction && !manifestEntry) return {
|
|
1274
1370
|
status: "rejected",
|
|
1275
1371
|
reason_code: "unsupported_action"
|
|
1276
1372
|
};
|
|
1373
|
+
const compatibility = evaluateCompatibility({
|
|
1374
|
+
action: plannedAction ?? itemAction,
|
|
1375
|
+
itemAction,
|
|
1376
|
+
itemRevision: args.item_revision,
|
|
1377
|
+
currentRevision: item.revision,
|
|
1378
|
+
enabled: p.enabled,
|
|
1379
|
+
integrity: p.integrity,
|
|
1380
|
+
hostStatus: p.hostStatus,
|
|
1381
|
+
itemKind: item.kind,
|
|
1382
|
+
itemStatus: item.status,
|
|
1383
|
+
authority: item.authority,
|
|
1384
|
+
legacyFlags: item.legacyFlags,
|
|
1385
|
+
authorityDisposition: item.authorityDisposition,
|
|
1386
|
+
holdsExecutionAuthority: itemHoldsExecutionAuthority(item),
|
|
1387
|
+
waitAuthorization: item.waitAuthorization,
|
|
1388
|
+
reboundFrom: item.reboundFrom,
|
|
1389
|
+
originalAuthority: item.reboundFrom ? (() => {
|
|
1390
|
+
const original = p.items.get(item.reboundFrom.itemId);
|
|
1391
|
+
return original ? {
|
|
1392
|
+
semanticAction: original.semanticAction,
|
|
1393
|
+
requestedTarget: original.requestedTarget
|
|
1394
|
+
} : void 0;
|
|
1395
|
+
})() : void 0,
|
|
1396
|
+
targetCaptureStatus: item.targetCaptureStatus,
|
|
1397
|
+
targetSourceKind: item.targetSource?.kind,
|
|
1398
|
+
requestedTarget: item.requestedTarget,
|
|
1399
|
+
...args.requested_target !== void 0 ? { resolvedTarget: args.requested_target } : item.requestedTarget ? { resolvedTarget: item.requestedTarget } : {},
|
|
1400
|
+
...item.requestedTarget !== void 0 ? { targetAuthorizes: plannedAction !== void 0 && isStatefulAction(plannedAction) ? requestedTargetAuthorizesMutation(plannedAction, item.requestedTarget, args.requested_target ?? item.requestedTarget) : true } : {},
|
|
1401
|
+
conflictingProhibition: plannedAction !== void 0 && isStatefulAction(plannedAction) && conflictsWithProhibition(p, plannedAction, item),
|
|
1402
|
+
adapterSupported: actionHasAdapter(plannedAction ?? itemAction)
|
|
1403
|
+
}, (requested, resolved) => plannedAction !== void 0 && isStatefulAction(plannedAction) ? requestedTargetMatchesResolved(plannedAction, requested, resolved) : true);
|
|
1404
|
+
const compatibilityView = {
|
|
1405
|
+
status: compatibility.status,
|
|
1406
|
+
assumed_action: compatibility.assumedAction,
|
|
1407
|
+
...compatibility.itemAction !== void 0 ? { item_action: compatibility.itemAction } : {},
|
|
1408
|
+
reason_codes: compatibility.reasonCodes,
|
|
1409
|
+
semantics_compatible: compatibility.semanticsCompatible,
|
|
1410
|
+
target_compatible: compatibility.targetCompatible,
|
|
1411
|
+
certifiable: compatibility.certifiable,
|
|
1412
|
+
...compatibility.requiredIdentityField !== void 0 ? { required_identity_field: compatibility.requiredIdentityField } : {},
|
|
1413
|
+
note: compatibility.status === "compatible" ? "This assumption matches the current obligation. Preparation itself still grants no authority." : compatibility.status === "incompatible" ? "This assumption is not what this obligation records. Prepare again with the item action, or record a fresh root instruction that authorizes the action you intended." : "This assumption matches the obligation, but this snapshot cannot execute yet. Clear the named condition first."
|
|
1414
|
+
};
|
|
1415
|
+
if (compatibility.status === "incompatible") return {
|
|
1416
|
+
status: "incompatible",
|
|
1417
|
+
item: {
|
|
1418
|
+
id: item.id,
|
|
1419
|
+
revision: item.revision
|
|
1420
|
+
},
|
|
1421
|
+
diagnosis,
|
|
1422
|
+
compatibility: compatibilityView,
|
|
1423
|
+
reason_code: compatibility.reasonCodes[0],
|
|
1424
|
+
note: compatibilityView.note
|
|
1425
|
+
};
|
|
1426
|
+
const recipe = plannedAction && isStatefulAction(plannedAction) ? actionPreparation(plannedAction) : void 0;
|
|
1427
|
+
const missingTargetFields = recipe ? recipe.selector_fields.filter((key) => !(item.requestedTarget?.[key] !== void 0 || args.requested_target?.[key] !== void 0)) : [];
|
|
1428
|
+
const callerTargetProposedKeys = item.targetCaptureStatus === "resolved" ? Object.keys(args.requested_target ?? {}).filter((key) => {
|
|
1429
|
+
const own = item.requestedTarget?.[key];
|
|
1430
|
+
const selectedByItem = own !== void 0;
|
|
1431
|
+
const plannedByRecipe = recipe?.selector_fields.includes(key) === true;
|
|
1432
|
+
if (!selectedByItem && !plannedByRecipe) return false;
|
|
1433
|
+
const proposed = args.requested_target?.[key];
|
|
1434
|
+
return proposed !== own && JSON.stringify(proposed) !== JSON.stringify(own);
|
|
1435
|
+
}) : [];
|
|
1277
1436
|
const reusable = [...p.evidence.values()].filter((evidence) => relevantEvidence(p, item, evidence) && evidenceAvailabilityReason(evidence) === void 0).sort((a, b) => b.toolResultSeq - a.toolResultSeq).slice(0, 8).map((evidence) => ({
|
|
1278
1437
|
evidence_id: evidence.id,
|
|
1279
1438
|
role: evidence.evidenceRole,
|
|
@@ -1286,8 +1445,6 @@ function createPrepareTool(options) {
|
|
|
1286
1445
|
"effect (the exact planned change)",
|
|
1287
1446
|
"state (independent post-state readback)"
|
|
1288
1447
|
] : ["effect (one matching durable verification fact)"];
|
|
1289
|
-
const recipe = plannedAction && isStatefulAction(plannedAction) ? actionPreparation(plannedAction) : void 0;
|
|
1290
|
-
const missingTargetFields = recipe ? recipe.selector_fields.filter((key) => !(item.requestedTarget?.[key] !== void 0 || args.requested_target?.[key] !== void 0)) : [];
|
|
1291
1448
|
const capability = plannedAction && options.hostCapability ? options.hostCapability(plannedAction) : void 0;
|
|
1292
1449
|
const commandShape = options.commandTemplate && plannedAction ? options.commandTemplate(plannedAction) : void 0;
|
|
1293
1450
|
return {
|
|
@@ -1297,6 +1454,7 @@ function createPrepareTool(options) {
|
|
|
1297
1454
|
revision: item.revision
|
|
1298
1455
|
},
|
|
1299
1456
|
diagnosis,
|
|
1457
|
+
compatibility: compatibilityView,
|
|
1300
1458
|
...plannedAction !== void 0 ? { planned_action: plannedAction } : {},
|
|
1301
1459
|
...commandShape !== void 0 ? { supported_command_shape: commandShape } : {},
|
|
1302
1460
|
required_evidence_order: requiredOrder,
|
|
@@ -1306,19 +1464,26 @@ function createPrepareTool(options) {
|
|
|
1306
1464
|
status: capability.status,
|
|
1307
1465
|
...capability.reasonCode !== void 0 ? { reason_code: capability.reasonCode } : {}
|
|
1308
1466
|
} } : {},
|
|
1309
|
-
...recipe ? {
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1467
|
+
...recipe ? {
|
|
1468
|
+
recipe_only: true,
|
|
1469
|
+
evidence_input_contract: {
|
|
1470
|
+
selector_fields: recipe.selector_fields,
|
|
1471
|
+
optional_selector_fields: recipe.optional_selector_fields,
|
|
1472
|
+
command_manifest_fields: recipe.command_manifest_fields,
|
|
1473
|
+
command_manifest_ids: recipe.command_manifest_ids,
|
|
1474
|
+
planned_tools: recipe.planned_tools,
|
|
1475
|
+
planned_argument_fields: recipe.planned_argument_fields,
|
|
1476
|
+
producer_fields: recipe.producer_fields,
|
|
1477
|
+
readback_fields: recipe.readback_fields,
|
|
1478
|
+
execution_surface: recipe.execution_surface,
|
|
1479
|
+
steps: recipe.steps
|
|
1480
|
+
}
|
|
1481
|
+
} : {},
|
|
1482
|
+
...callerTargetProposedKeys.length > 0 ? { caller_target_is_proposal: {
|
|
1483
|
+
fields: callerTargetProposedKeys,
|
|
1484
|
+
note: "The supplied requested_target differs from the target this obligation selected. It is recorded as the caller's proposal for the plan only; authorization still compares the obligation's own target."
|
|
1320
1485
|
} } : {},
|
|
1321
|
-
note: "Preparation performs no action. A default or guessed target is not user authority; explicit root instruction is required for missing target fields."
|
|
1486
|
+
note: callerTargetProposedKeys.length > 0 ? "Preparation performs no action. The supplied requested_target is NOT the target this obligation selected and is not authority; the recipe below is recipe_only. Resolve the item target through context_guard_evidence before executing." : "Preparation performs no action. A default or guessed target is not user authority; explicit root instruction is required for missing target fields."
|
|
1322
1487
|
};
|
|
1323
1488
|
}
|
|
1324
1489
|
});
|
|
@@ -4498,6 +4663,37 @@ function authorizeMutationFromProjection(projection, request) {
|
|
|
4498
4663
|
status: "denied",
|
|
4499
4664
|
reasonCode: "mutation_contract_item_not_pending"
|
|
4500
4665
|
};
|
|
4666
|
+
const compatibility = evaluateCompatibility({
|
|
4667
|
+
action: request.action,
|
|
4668
|
+
itemAction: item.semanticAction ?? "generic_run",
|
|
4669
|
+
itemRevision: request.contractItemRevision,
|
|
4670
|
+
currentRevision: item.revision,
|
|
4671
|
+
itemKind: item.kind,
|
|
4672
|
+
itemStatus: item.status,
|
|
4673
|
+
authority: item.authority,
|
|
4674
|
+
legacyFlags: item.legacyFlags,
|
|
4675
|
+
authorityDisposition: item.authorityDisposition,
|
|
4676
|
+
waitAuthorization: item.waitAuthorization,
|
|
4677
|
+
reboundFrom: item.reboundFrom,
|
|
4678
|
+
originalAuthority: item.reboundFrom ? (() => {
|
|
4679
|
+
const original = projection.items.get(item.reboundFrom.itemId);
|
|
4680
|
+
return original ? {
|
|
4681
|
+
semanticAction: original.semanticAction,
|
|
4682
|
+
requestedTarget: original.requestedTarget
|
|
4683
|
+
} : void 0;
|
|
4684
|
+
})() : void 0,
|
|
4685
|
+
targetCaptureStatus: item.targetCaptureStatus,
|
|
4686
|
+
targetSourceKind: item.targetSource?.kind,
|
|
4687
|
+
requestedTarget: item.requestedTarget,
|
|
4688
|
+
adapterSupported: actionHasAdapter(request.action)
|
|
4689
|
+
}, (requested, resolved) => requestedTargetMatchesResolved(request.action, requested, resolved));
|
|
4690
|
+
if (compatibility.status === "incompatible") return compatibility.reasonCodes.includes("action_not_compatible_with_item") ? {
|
|
4691
|
+
status: "denied",
|
|
4692
|
+
reasonCode: "mutation_semantic_action_mismatch"
|
|
4693
|
+
} : {
|
|
4694
|
+
status: "denied",
|
|
4695
|
+
reasonCode: "rebind_does_not_authorize_mutation"
|
|
4696
|
+
};
|
|
4501
4697
|
if (item.authorityDisposition === "conditional_wait" || item.waitAuthorization) return {
|
|
4502
4698
|
status: "denied",
|
|
4503
4699
|
reasonCode: item.authorityDisposition === "conditional_wait" ? "mutation_awaiting_root_condition" : "mutation_awaiting_root_wait"
|
|
@@ -4533,6 +4729,10 @@ function authorizeMutationFromProjection(projection, request) {
|
|
|
4533
4729
|
status: "denied",
|
|
4534
4730
|
reasonCode: "mutation_target_clarification_required"
|
|
4535
4731
|
};
|
|
4732
|
+
if (item.targetSource?.kind === "environment_default") return {
|
|
4733
|
+
status: "denied",
|
|
4734
|
+
reasonCode: "mutation_target_environment_default"
|
|
4735
|
+
};
|
|
4536
4736
|
const boundedAuthorized = (scope) => requestedTargetAuthorizesMutation(request.action, {
|
|
4537
4737
|
...item.requestedTarget,
|
|
4538
4738
|
scope
|
|
@@ -4546,6 +4746,10 @@ function authorizeMutationFromProjection(projection, request) {
|
|
|
4546
4746
|
status: "denied",
|
|
4547
4747
|
reasonCode: "mutation_conflicting_prohibition"
|
|
4548
4748
|
};
|
|
4749
|
+
if (!itemHoldsExecutionAuthority(item)) return {
|
|
4750
|
+
status: "denied",
|
|
4751
|
+
reasonCode: "mutation_item_not_executable"
|
|
4752
|
+
};
|
|
4549
4753
|
return {
|
|
4550
4754
|
status: "authorized",
|
|
4551
4755
|
reasonCode: "mutation_root_contract_authorized"
|
|
@@ -5367,4 +5571,4 @@ function normalizeGoalState(value) {
|
|
|
5367
5571
|
}
|
|
5368
5572
|
|
|
5369
5573
|
//#endregion
|
|
5370
|
-
export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION, ALPHA2_DSHMARKET_139_HOST_PACKAGES, ALPHA2_HOST_PACKAGES, ALPHA3_HOST_PACKAGES, BASE_HOST_PACKAGES, BOUNDED_ARTIFACT_TYPES, CAPTURE_V042_NOTICE, CERTIFICATE_VERSION, CERTIFICATE_VERSION_V2, CLEANUP_CONDITION_RULE, CLEANUP_CONDITION_RULE_COMPACT, CLEANUP_CONDITION_RULE_SHORT, COMMAND_SURFACE_MANIFEST, CONFIRM_LINE_PATTERN, CONTROL_RECORD_PREFIX, Config, DEFAULT_DELEGATION_TOOL_NAMES, DEFAULT_HOST_LOCK, DEFAULT_RECOVERY_CHAR_BUDGET, DEPENDENCY_FREE_ONLY_CONDITION, EXPECTED_HOST_PACKAGES, FIRST_STEP_GUIDANCE, GIT_COMMAND_MANIFEST_IDS, GIT_COMMAND_TEMPLATES, GOAL_HOST_PACKAGES, HOST_CAPABILITY_PACKAGE_GROUPS, HOST_COHORTS, HostProfileError, LATEST_SUPPORTED_HOST_VERSION, LEGACY_HOST_COHORTS, MIN_RECOVERY_CHAR_BUDGET, MIN_SUPPORTED_HOST_VERSION, NO_PROGRESS_RECORD_PREFIX, NO_PROGRESS_TURNS_BEFORE_STOP, PROOF_CAPABILITY_MATRIX, PROOF_KINDS, PROOF_KINDS_V2, PROOF_MANIFEST_DOMAIN_V2, PROOF_PROTOCOL_VERSION, PROOF_PROTOCOL_VERSION_V2, PROTOCOL_V3_NOTICE, PROTOCOL_V4_NOTICE, PROTOCOL_V5_NOTICE, RC015_HOST_PACKAGES, RC015_RC2_HOST_PACKAGES, RC1_HOST_PACKAGES, SEMANTIC_ACTIONS, SESSION_API_UNSUPPORTED, SESSION_EVENT_ENVELOPE_INVALID, STATEFUL_ACTIONS, STOP_PROTOCOL_VERSION, STOP_PROTOCOL_VERSION_V2, SUPPORTED_EVIDENCE_ADAPTERS, SUPPORTED_HOST_RANGE, SUPPORTED_HOST_VERSIONS, SessionApiError, actionCompatible, actionHasCertificationPath, admissibleForRemoval, apply, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, capabilityConsequence, capabilityFactOf, capabilityRemedyPhrase, captureClause, captureItem, carriesCleanupCondition, certifyCheckpoint, claimedBatchHasRealRootInput, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, cleanupConditionFor, closingHint, combineHostPolicy, commitIndexSnapshotDigest, commitTreeSnapshotDigest, compareHostVersions, confirmRebind, createGitPrestateEnvelope, createProjection, createProofManifest, createProofManifestV2, currentContractDigest, decideTurnBoundary, decideTurnStopping, decisionBoundaryKey, deriveItemDiagnosis, deriveProjection, digestStrings, effectuateBoundary, evaluateExternalWaitCapability, evaluateHostCapability, evaluateHostLock, evaluateMinimumHostVersion, evaluateToolSurfaceCapability, evidenceAvailabilityReason, evidenceCoverage, evidenceFromPersistedToolResult, evidenceMatchesItem, executeRevalidatedGitEffect, extractArtifactPaths, extractMethod, extractOperation, extractTextContent, extractToolSubject, firstStepGuidance, gitCommandMatchesTarget, goalCompletionDenial, hasCurrentCertificate, hostLockContextFromComposedDump, hostLockRowsFromComposedDump, hostVersionFromPackages, inject, injectActiveProfileHostLock, inspectTargetHostGraph, interpretClause, interpretMessage, isCurrentAcceptedBoundary, isDeterministicCheck, isExecutableItem, isFrozenV042RebindResponse, isInformationalMessage, isOpenObligation, isRootPauseRequest, isRunExecutable, isStatefulAction, isVerifyingCapability, isWholeTaskCompletionClaim, itemDiagnosis, kindOfScope, latestAssistantText, latestRootInstruction, lifecyclePhase, maskCodeSpans, name, namedActions, normalizeClause, observeAssistantOutcome, openItems, packageRowsFromActiveGraph, packageRowsFromPnpmLock, parseConfirmationMessage, parseGitCommandManifest, parseHostVersion, parsePwshCommand, parseShellCommand, partialFailureOf, previewFirstStepInjection, progressFingerprint, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualifyBoundary, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, relevantEvidence, removalIsComplete, removalIsPartiallyKnown, renderRecoveryPacket, replayRebindResult, requestedIdentityKey, requestedTargetAuthorizesMutation, requestedTargetMatchesResolved, requiredSubjectsOf, resolveActiveProfileHostLock, resolveInstalledHostLock, revalidateGitPrestate, sanitizeClauseText, sanitizeUrl, satisfiesSupportedHostRange, scopeCoverageDigest, segmentAuthorityBlocks, segmentClauses, selectHostCohort, semanticActionFromCommand, semanticActionFromText, semanticActionOfScope, sessionQuery, sessionQueryV2, sha256, snapshotSessionEvents, statefulActionsOfScope, supersedeItem, validateActionManifest, validateActionTarget, validateManifest, validateProofManifest, validateProofManifestV2, verifiedLinearCommitReadback, verifyComposedHostLockDump, withDurability };
|
|
5574
|
+
export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION, ALPHA2_DSHMARKET_139_HOST_PACKAGES, ALPHA2_HOST_PACKAGES, ALPHA3_HOST_PACKAGES, BASE_HOST_PACKAGES, BOUNDED_ARTIFACT_TYPES, CAPTURE_V042_NOTICE, CERTIFICATE_VERSION, CERTIFICATE_VERSION_V2, CLEANUP_CONDITION_RULE, CLEANUP_CONDITION_RULE_COMPACT, CLEANUP_CONDITION_RULE_SHORT, COMMAND_SURFACE_MANIFEST, CONFIRM_LINE_PATTERN, CONTROL_RECORD_PREFIX, Config, DEFAULT_DELEGATION_TOOL_NAMES, DEFAULT_HOST_LOCK, DEFAULT_RECOVERY_CHAR_BUDGET, DEPENDENCY_FREE_ONLY_CONDITION, EXPECTED_HOST_PACKAGES, FIRST_STEP_GUIDANCE, GIT_COMMAND_MANIFEST_IDS, GIT_COMMAND_TEMPLATES, GOAL_HOST_PACKAGES, GRANTED_QUALIFICATION, HOST_CAPABILITY_PACKAGE_GROUPS, HOST_COHORTS, HostProfileError, LATEST_SUPPORTED_HOST_VERSION, LEGACY_HOST_COHORTS, LEGACY_QUALIFICATION, MIN_RECOVERY_CHAR_BUDGET, MIN_SUPPORTED_HOST_VERSION, NO_PROGRESS_RECORD_PREFIX, NO_PROGRESS_TURNS_BEFORE_STOP, PROOF_CAPABILITY_MATRIX, PROOF_KINDS, PROOF_KINDS_V2, PROOF_MANIFEST_DOMAIN_V2, PROOF_PROTOCOL_VERSION, PROOF_PROTOCOL_VERSION_V2, PROTOCOL_V3_NOTICE, PROTOCOL_V4_NOTICE, PROTOCOL_V5_NOTICE, RC015_HOST_PACKAGES, RC015_RC2_HOST_PACKAGES, RC1_HOST_PACKAGES, SEMANTIC_ACTIONS, SESSION_API_UNSUPPORTED, SESSION_EVENT_ENVELOPE_INVALID, STATEFUL_ACTIONS, STOP_PROTOCOL_VERSION, STOP_PROTOCOL_VERSION_V2, SUPPORTED_EVIDENCE_ADAPTERS, SUPPORTED_HOST_RANGE, SUPPORTED_HOST_VERSIONS, SessionApiError, actionCompatible, actionHasCertificationPath, actionVerbMatches, admissibleForRemoval, apply, applyUpgradeEligibility, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, capabilityConsequence, capabilityFactOf, capabilityRemedyPhrase, captureClause, captureItem, carriesCleanupCondition, certifyCheckpoint, claimedBatchHasRealRootInput, clarifiedSpanOf, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, clauseAsksOwnQuestion, clauseIsGoverned, clauseIsProtected, cleanupConditionFor, closingHint, combineHostPolicy, commitIndexSnapshotDigest, commitTreeSnapshotDigest, compareHostVersions, confirmRebind, createGitPrestateEnvelope, createProjection, createProofManifest, createProofManifestV2, currentContractDigest, decideTurnBoundary, decideTurnStopping, decisionBoundaryKey, deriveItemDiagnosis, deriveProjection, digestStrings, effectuateBoundary, environmentDefaultRepositoryTarget, evaluateExternalWaitCapability, evaluateHostCapability, evaluateHostLock, evaluateMinimumHostVersion, evaluateToolSurfaceCapability, evidenceAvailabilityReason, evidenceCoverage, evidenceFromPersistedToolResult, evidenceMatchesItem, executeRevalidatedGitEffect, explanationHasActionResidue, extractArtifactPaths, extractMethod, extractOperation, extractTextContent, extractToolSubject, firstStepGuidance, gitCommandMatchesTarget, goalCompletionDenial, governedClauseRestrictsExecution, hasCurrentCertificate, hasOrderedCoordination, hasQuestionScope, hostLockContextFromComposedDump, hostLockRowsFromComposedDump, hostVersionFromPackages, inject, injectActiveProfileHostLock, inspectTargetHostGraph, interpretClause, interpretMessage, introducesActionClause, isCurrentAcceptedBoundary, isDeterministicCheck, isExecutableItem, isExplanationScope, isFrozenV042RebindResponse, isInformationalFragment, isInformationalMessage, isOpenObligation, isQuestionScopeNeedingReview, isRestatement, isRootPauseRequest, isRunExecutable, isStatefulAction, isVerifyingCapability, isWholeTaskCompletionClaim, itemDiagnosis, itemHoldsExecutionAuthority, kindOfScope, latestAssistantText, latestRootInstruction, legacyQuestionReadingIsInformational, legacyRecordsNeedingReview, lifecyclePhase, maskCodeSpans, maskQuotedSpans, name, namedActions, normalizeClause, observeAssistantOutcome, openItems, opensWithDirective, packageRowsFromActiveGraph, packageRowsFromPnpmLock, parseConfirmationMessage, parseGitCommandManifest, parseHostVersion, parsePwshCommand, parseShellCommand, partialFailureOf, previewFirstStepInjection, progressFingerprint, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualificationOfClause, qualifyBoundary, questionHeadsClause, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, relevantEvidence, removalIsComplete, removalIsPartiallyKnown, renderRecoveryPacket, replayRebindResult, reportingHeadGoverns, requestedIdentityKey, requestedTargetAuthorizesMutation, requestedTargetMatchesResolved, requiredSubjectsOf, resolveActiveProfileHostLock, resolveInstalledHostLock, restatedContentOf, revalidateGitPrestate, sanitizeClauseText, sanitizeUrl, satisfiesSupportedHostRange, scopeCoverageDigest, segmentAuthorityBlocks, segmentClauses, selectHostCohort, semanticActionFromCommand, semanticActionFromText, semanticActionOfScope, sessionQuery, sessionQueryV2, sha256, snapshotSessionEvents, splitTextFragments, statefulActionsOfScope, supersedeItem, validateActionManifest, validateActionTarget, validateManifest, validateProofManifest, validateProofManifestV2, verbIsNegated, verifiedLinearCommitReadback, verifyComposedHostLockDump, withDurability };
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -47,6 +47,10 @@ Recovery packets keep the existing content-dedup and ride the next entered step.
|
|
|
47
47
|
|
|
48
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.
|
|
49
49
|
|
|
50
|
+
0.6.3 adds one shared compatibility judgement (`src/domain/compatibility.ts`) that both preparation and the mutation gate call for the same item, action, revision and target. It separates four different facts — semantic compatibility (does the action belong to the item's reading?), target compatibility (is the resolved target the one the obligation selected?), execution readiness (pending, authorized, free of an outstanding condition or constraint), and adapter capability — and returns `compatible`, `incompatible` (the assumption is not what the obligation records, with the item's own action named) or `blocked` (the assumption matches but this snapshot cannot execute yet). A caller-supplied action manual is returned as `recipe_only`, and a caller-supplied target the obligation did not select is reported as a proposal, never as authority; the side-effect entry still re-reads every fact, evidence, host lock and identity before acting. The same release adds a pre-terminal eligibility pass: before any terminal filtering, records that earlier versions closed as answered are re-read, and one whose own text still orders work or whose git target has no auditable source is marked `needs_review`. That mark preserves the historical status byte for byte, re-executes nothing, and blocks a new certificate and Goal completion instead of warning about them.
|
|
51
|
+
|
|
52
|
+
Requested-target provenance (`targetSource`) is recorded beside the target itself: an explicit name or path, a phrase that selects the current repository, a trusted host selection, a unique selection inherited from another obligation of the same work unit, or the environment default. Only the first four are user selections; the environment default is context that can resolve an allowed object but can never authorize one.
|
|
53
|
+
|
|
50
54
|
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.
|
|
51
55
|
|
|
52
56
|
## Synchronization
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# 0.6.3 合同修订说明(收窄自动授权范围)
|
|
2
|
+
|
|
3
|
+
状态:**用户明确批准的验收合同调整**,不是对旧合同的“全部实现”声明。本文列出被替代的验收条目、
|
|
4
|
+
代价、替代它们的结构性不变量,以及仍然有效的条目。历史材料
|
|
5
|
+
([开发计划](DEVELOPMENT_PLAN_0_6_3.md)、[0.6.2 复核](REVIEW_0_6_2_CORE_ALIGNMENT.md)、
|
|
6
|
+
[执行提示](EXECUTE_0_6_3_PROMPT.md)、历轮[验收记录](LOCAL_ACCEPTANCE.md))保持原样,不静默改写;
|
|
7
|
+
本文只记录它们之上的一次显式变更。
|
|
8
|
+
|
|
9
|
+
## 1. 为什么修订
|
|
10
|
+
|
|
11
|
+
上一版 0.6.3 合同要求:调查/解释/疑问头治理其句子,**同时**“同句调查之后的第二条指令必须自动授权”。
|
|
12
|
+
满足该要求只能靠“补语是否闭合”的猜测规则(状态词命中、主体词表未命中、工作动词命中、位置与长度窗口)。
|
|
13
|
+
十四轮独立复核逐条证明这些推断在开放类别上不可靠:状态词可以是动作的宾语或修饰语,主体可以出现在任何
|
|
14
|
+
位置,动作词可以完全不在词表内。每一次修补都只是把猜测换成另一条猜测。
|
|
15
|
+
|
|
16
|
+
本次修订把要求收窄为**可证明**的形态:不能证明“该动作是独立指令”时,保留未决义务并拒绝执行授权。
|
|
17
|
+
|
|
18
|
+
## 2. 被替代的验收条目(原文保留在 LOCAL_ACCEPTANCE 的历轮记录中)
|
|
19
|
+
|
|
20
|
+
| 被替代的条目 | 现在的合同 |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `Check whether an update exists and install the package.` 的第二动作必须授权 | 允许保守进入**未决**;不再要求自动授权 |
|
|
23
|
+
| `检查是否有新版本并且安装这个主题。` 的第二动作必须授权 | 同上 |
|
|
24
|
+
| `检查是否有更新并安装新主题。`、`检查服务是否正常并记录变更。`、`确认缓存是否有效并安装依赖。`、`Check whether the cache is valid and install the package.`、`Verify whether the lock file is current and install the package.`、`有没有最新版本并…` 等“已证明是状态疑问”的正例必须保留其并列指令 | 同一治理范围内的并列动作一律**未决**;不再按“状态疑问”区分 |
|
|
25
|
+
| `解释头治理的句子在其补语已闭合时,并列小句开启新谓语,其指令照常保留`(`说明…的作用,然后更新 README。`) | 解释头治理**整句**,句中并列一律未决;只有**另起一句**的指令仍可授权 |
|
|
26
|
+
| 句末问号/标点/拆分可以把先前的指令保留下來(`What changed, and update the README?` 的 README 更新) | 同句疑问与动作混排即未决;标点本身不构成授权 |
|
|
27
|
+
| “命令式调查的补语若能证明是状态疑问则闭合” | 该闭合规则**整体删除**,不再保留第二条授权路径 |
|
|
28
|
+
|
|
29
|
+
**代价**(明确接受):在同一子句内把“问一句 + 顺手安排一件事”的写法视为未决,用户需要**另写一句**
|
|
30
|
+
明确指令才能授权;无法命名的状态与被证实为动作的内容都不再获得自动授权。安全方向优先。
|
|
31
|
+
|
|
32
|
+
## 3. 仍然有效、且被本次修订加强的条目
|
|
33
|
+
|
|
34
|
+
1. 纯问答仍可回答(`检查是否有新版本。`、`Is there any update for the plugin?`、对象列表疑问)。
|
|
35
|
+
2. 普通明确指令仍可执行(`重启 api 服务。`)。
|
|
36
|
+
3. **明确脱离受限范围的独立指令**仍可授权:另起一句(`Explain how the team deploys. Then restart service api.`)
|
|
37
|
+
或另起一个分句(`检查是否存在更新;安装新主题;`)。
|
|
38
|
+
4. 未决义务**必须保留**:不产生 `items = []`,不能被普通回答关闭,不能取得完成证书。
|
|
39
|
+
5. 引号、代码、转述等父范围继续保留:受限范围内的动作永不是授权。
|
|
40
|
+
6. K2 目标身份、K3 prepare/execute 一致性、K4 旧记录资格与历史保真继续有效;旧记录**不再默认获得**新授权。
|
|
41
|
+
|
|
42
|
+
## 4. 替代机制:资格(qualification)
|
|
43
|
+
|
|
44
|
+
- 读取层在**任何分区之前**为每个子句建立一次 `ExecutionQualification`:
|
|
45
|
+
`granted` 或 `restricted`。**`granted` 是正面结论,不是默认值**:只有在子句自身范围既无疑问内容
|
|
46
|
+
(疑问词、是非标记、`?`/`?`、A-不-A 等),又确实命名了读取层能识别的动作时才成立;
|
|
47
|
+
其余一切(未分类的疑问内容 `I wonder whether …`、后置 `是否可行`、无法识别的动作形态)一律
|
|
48
|
+
`restricted`(`unproven_scope`),因此“未命中治理模式即授予”不成立。
|
|
49
|
+
- **指令的正面判据是"祈使",不是"提到了动作"**:`The technicians restart service api every
|
|
50
|
+
night.` 与 `日志显示运维人员重启 api 服务。` 只是陈述,不构成指令;`granted` 现在要求子句是
|
|
51
|
+
**root 自己语气的祈使句**(`opensWithDirective`:消费请求前缀后动作位于句首,或句首是闭类的
|
|
52
|
+
施事/处所/时间/对象短语 `由你…`、`在仓库…`、`按 P0—P4…`、`明天…`),并排除报告体。
|
|
53
|
+
仅"命名了动作"不再授予资格。由此 `restricted` 与 disposition 被强制一致:受限子句不会再出现
|
|
54
|
+
`executable_now`,而是 `unresolved`。
|
|
55
|
+
- **父范围先于切分成立**:引号(`"…"`、`“…”`、词边界处的 `'…'`、`「…」`、`『…』`)与代码跨度
|
|
56
|
+
拥有自己的标点,引号内的句号/问号不再切开外层子句;受保护子句在连接符处不可再分。
|
|
57
|
+
`Explain this instruction: "Install foo. Restart service api."` 与
|
|
58
|
+
`解释这条指令:「安装 foo。重启 api 服务。」` 因此都是**一条**受限义务。等待/恢复标记
|
|
59
|
+
(`waitAuthorization`、resume marker)同样只读 root 自己的话,引号内的回声不再构成保留。
|
|
60
|
+
- **显式重述按"重述内容 + 身份绑定"授权**:重述先取出被重述的跨度(`restatedContentOf`),
|
|
61
|
+
再让它通过**与普通子句相同的判据**(`qualificationOfClause`:无疑问内容、祈使句首、非描述谓语),
|
|
62
|
+
或确认它是**规范操作规格**(`restatedContentIsOperation`:句首是操作,或首词/首二字解析为操作)。
|
|
63
|
+
仅"文中出现动作"不成立:`把重启 api 服务记为需要讨论的重启操作。`、
|
|
64
|
+
`把重启 api 服务明确为解释重启流程。`、
|
|
65
|
+
`Record restart service api as a description of how technicians restart service api.`
|
|
66
|
+
一律 `restricted`。同时**资格绑定到重述后的动作与目标**:捕获时 `semanticAction` 与
|
|
67
|
+
`actionPlan` 取自被重述的跨度,因此 `把重启 api 服务明确为检查日志。` 即便被授予,其身份是
|
|
68
|
+
"检查日志"而不是重启——重述之前的动作永远不会因此获得授权。合法用法
|
|
69
|
+
(`把更新插件明确为 apply package demo@2.0.0 profile web`、`把应用包 … 明确为 apply`、
|
|
70
|
+
`…明确为 inspect_remote_updates`)仍是 sanctioned 的 `granted` 路径,也是无法识别的动作形态
|
|
71
|
+
获得授权的唯一文本路径(裸写 `应用包 foo …` 不再授予资格)。
|
|
72
|
+
- **句首是动作仍不等于祈使**:`重启 api 服务是一个危险操作。`、`Restart service api is
|
|
73
|
+
dangerous.` 的主语就是那个动作,属描述句。`opensWithDirective` 因此要求动作所在子句的
|
|
74
|
+
**谓语不是描述性的**(`是/属于/意味着/导致…`、`is/are/means/causes…`,且只看动作所在的那个
|
|
75
|
+
子句,相对从句与后续子句不参与判定)。
|
|
76
|
+
- 由此产生的**代价**:动作词表之外的祈使形态(例如 `打包日志以便确认哪些请求失败。` 的“打包”)
|
|
77
|
+
也被判为 `restricted` —— 拒绝授权而不是猜测。该边界是安全方向,且只有正面证据能改变它。
|
|
78
|
+
- 分区、投影、恢复、prepare 都**不能**新增执行权限:子项继承父范围的资格(`inherited_restriction`),
|
|
79
|
+
不会因为自己带动作头而被提升为 `executable_now`。
|
|
80
|
+
- 变更门禁与 prepare 消费**同一份**存储资格(`itemHoldsExecutionAuthority`),并对 `semanticAction`
|
|
81
|
+
与 `actionPlan` 中的**每一个**动作适用;二者都不再重新分析文本。
|
|
82
|
+
- 资格缺失(0.6.3 之前的记录)→ 拒绝授权,并由升级资格检查给出
|
|
83
|
+
`legacy_missing_execution_qualification`,历史状态/文本/`answeredBy` 一律不改写。
|
|
84
|
+
|
|
85
|
+
数据流(可在测试中直接读出):
|
|
86
|
+
`interpretMessage().qualification` → `captureClause().executionQualification` →
|
|
87
|
+
投影/恢复持久化 → `itemHoldsExecutionAuthority()` → 门禁 / prepare。
|
|
88
|
+
|
|
89
|
+
- **新旧跨度各自验证唯一性,再逐字段合并**:同一跨度出现两个候选即记为
|
|
90
|
+
`requested_target_field_ambiguous` 并要求澄清(`把重启 api 服务或 worker 服务明确为 restart。`、
|
|
91
|
+
`把重启 api 服务明确为重启 worker 服务或 cache 服务。`);新跨度显式给出的字段优先,**省略的每个
|
|
92
|
+
字段**在被澄清义务唯一时继承(`把应用包 foo 版本 0.6.3 配置档 default 明确为 apply package foo
|
|
93
|
+
version 0.6.4。` 保留 `profile=default` 并采用新 `version`),旧选择有歧义则不继承并拒绝;主动作与
|
|
94
|
+
`actionPlan` 共用同一规则。
|
|
95
|
+
|
|
96
|
+
- **候选枚举与目标提取共用同一语法与规范化**:候选集合由提取器自己的解析器(label-first、
|
|
97
|
+
动词-宾语、名词后缀三种形态)枚举,每种形态内部独立判歧义,因此
|
|
98
|
+
`Rebind restart service api or worker as restart.` 与
|
|
99
|
+
`Rebind restart service api as restart service worker or cache.` 的共享标签列表不会再漏检;
|
|
100
|
+
`actionPlan` 的每个条目同样调用该检查(`restatedSpanAmbiguous`),主动作与计划共用一条规则。
|
|
101
|
+
|
|
102
|
+
- **唯一性覆盖动作的完整身份字段**:枚举按动作的身份字段合同逐字段进行——service、package、
|
|
103
|
+
version、profile、registry、repository、branch、remote、refspec——而不是只看对象名;
|
|
104
|
+
`version 0.6.4 or 0.6.5`、`profile web or prod` 因此与 `service api or worker` 一样被判为歧义。
|
|
105
|
+
重述路径读"被澄清跨度"而非整句(整句必然同时含新旧值,会被自身误判为歧义)。边界:该审计应用于
|
|
106
|
+
需要调和两个跨度的**重述**合并;普通子句沿用既有提取器的单一读数(既有 fixture 族不变)。
|
|
107
|
+
|
|
108
|
+
- **唯一性审计覆盖普通捕获、重述与动作计划**:普通分支此前直接采用单值提取结果,现已与重述共用
|
|
109
|
+
同一结果(`restatedSpanAmbiguous` 按动作的完整身份字段合同枚举),动作计划的每个条目同样消费它。
|
|
110
|
+
`Restart service api or worker.` 与 `提交仓库 /repo-a 分支 main 或 release。` 因此都是
|
|
111
|
+
`requested_target_field_ambiguous` + `clarification_required`。为使普通入口可用,枚举与提取
|
|
112
|
+
统一使用同一套**带边界的标签/动词定义**(`IDENTITY_LABELS`):标签值必须与标签分隔(避免把
|
|
113
|
+
`/repo-a`、`synthetic-plugin`、`repo/sub` 里的片段读成第二个候选),拉丁语标签/动词不被路径或
|
|
114
|
+
复合词中的字符吞并,中文标签仍可在 `把/将` 之后直接出现。
|
|
115
|
+
|
|
116
|
+
- **候选值按各字段的身份规则规范化,不做统一小写**:标签可以大小写不敏感,但分支、refspec、
|
|
117
|
+
repository、remote 等 Git 身份值区分大小写(`main 或 Main`、`main:main or main:Main` 都是两个
|
|
118
|
+
候选 → 歧义拒绝),package 走包名解析、registry 走规范形式;**完全相同的值仍然只算一个候选**
|
|
119
|
+
(`main 或 main` 通过)。
|
|
120
|
+
|
|
121
|
+
- **包规格是完整字段元组**:`foo@1.0.0` 与 `foo@2.0.0` 是两个目标(同名不同版本),
|
|
122
|
+
`foo@1.0.0 version 2.0.0` 是同一字段的冲突——两者的版本候选合并且逐字段验证;完全相同的重复值
|
|
123
|
+
仍只算一个候选。**审计与提取共用全部字段标签**:中文 `引用规范` 等标签同样纳入枚举(此前只在
|
|
124
|
+
提取器里存在)。
|
|
125
|
+
|
|
126
|
+
## 5. 与上游的关系
|
|
127
|
+
|
|
128
|
+
上游 Codex Context Guard 仍按自己的判据运行:本次修订只改 DSH 一侧的授权范围,
|
|
129
|
+
跨端台账 `tests/fixtures/cross-end/core_alignment_0_6_3.json` 以修订 4 记录该变化
|
|
130
|
+
(`mixed-conjunction-zh` 从“1 信息 + 1 指令”变为“1 未决”),两端**仍然都不授权**该安装,
|
|
131
|
+
但机制与信息量不同;不得据此推断任何跨端等价或原生能力。
|
|
132
|
+
|
|
133
|
+
## 6. 未测量的能力(不因本次修订改变)
|
|
134
|
+
|
|
135
|
+
原生宿主恢复与 Codex 宿主轮次、候选 CI、冻结 tgz 与精确制品验收、macOS/Windows 原生验收、
|
|
136
|
+
真实模型行为、插件安装与 DSH 重启、tag 与发布,均仍未测量。本修订与这些事实无关。
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "agent-handoff/v1",
|
|
3
|
+
"state": "ready",
|
|
4
|
+
"repositories": [
|
|
5
|
+
{
|
|
6
|
+
"id": "dsh",
|
|
7
|
+
"url": "https://github.com/GreenLv/dsh-completion-guard",
|
|
8
|
+
"base_sha": "63326f22d40407099baa70c8947c37029749588e",
|
|
9
|
+
"head_sha": "63326f22d40407099baa70c8947c37029749588e",
|
|
10
|
+
"change_paths": [
|
|
11
|
+
"docs/REVIEW_0_6_2_CORE_ALIGNMENT.md",
|
|
12
|
+
"docs/DEVELOPMENT_PLAN_0_6_3.md",
|
|
13
|
+
"docs/DEVELOPMENT_HANDOFF_0_6_3.json",
|
|
14
|
+
"docs/EXECUTE_0_6_3_PROMPT.md"
|
|
15
|
+
],
|
|
16
|
+
"dirty_scope": {
|
|
17
|
+
"staged": [],
|
|
18
|
+
"unstaged": [],
|
|
19
|
+
"untracked": [
|
|
20
|
+
"docs/REVIEW_0_6_2_CORE_ALIGNMENT.md",
|
|
21
|
+
"docs/DEVELOPMENT_PLAN_0_6_3.md",
|
|
22
|
+
"docs/DEVELOPMENT_HANDOFF_0_6_3.json",
|
|
23
|
+
"docs/EXECUTE_0_6_3_PROMPT.md"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"dirty_scope_sha256": "11137fab1b77914b41ef678ba5b353bb68df2e1c5bc868db08513ab541ddc796",
|
|
27
|
+
"prepared_source_sha256": null
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"requirements": [
|
|
31
|
+
"在 dsh-completion-guard 仓库执行 0.6.3 本地开发。先读 AGENTS.md、docs/DEVELOPMENT_PLAN_0_6_3.md 和 docs/REVIEW_0_6_2_CORE_ALIGNMENT.md,核对真实 HEAD、已有修改和写入权,保留他人工作。",
|
|
32
|
+
"一次连续完成计划 D063-01 至 D063-06;以 K1-K4 和 T01-T08 为验收合同,从语义作用域、目标来源、准备/执行共用判据和旧状态资格入手,不逐句补关键词,不放宽正确拒绝。",
|
|
33
|
+
"先用独立期望复现三类旧缺陷,再实施修复。准备未参与实现调参的留出集;失败不得改期望迎合实现。纯信息、明确执行与合法唯一目标必须有正向对照,不能全 unresolved 过关。",
|
|
34
|
+
"旧 answered/closed 在终态过滤前做接受资格检查;不改历史字节,不自动重做历史操作。prepare 后目标或证据变化即使 revision 未变也要重新判断。",
|
|
35
|
+
"实现、测试、双语文档与 changelog、版本 0.6.3 和生成 dist 一起完成;按计划运行适用本地门槛及完整确定性矩阵,记录命令与结果。跨端源入口合成测试允许;真实宿主或跨平台验收不在本轮。",
|
|
36
|
+
"完成后自己审查整条链和相邻反例,修复 P1/P2 后重跑受影响检查。交回实际 diff、根因到测试的映射、命令/退出码、留出集结果、自审发现及处理、剩余风险和待验证门槛。",
|
|
37
|
+
"范围内工作自主连续完成,不逐阶段等确认。仅在缺必要输入、不可解除阻塞或必须改变已授权范围时报告具体阻塞;不得自降验收门槛。",
|
|
38
|
+
"全部本地工作完成后保持未提交,停止在提交及跨平台/原生验证之前,等待用户或协调者核验候选;不要自行进入发布阶段。"
|
|
39
|
+
],
|
|
40
|
+
"out_of_scope": [
|
|
41
|
+
"禁止 git add/commit/push/merge、tag、发布、触发远端 CI 或跨主机调度。",
|
|
42
|
+
"禁止安装或升级用户真实插件、重启 DSH、执行真实宿主/模型原生验收、重放事故安装/提交/推送效果。",
|
|
43
|
+
"禁止修改 codex-sync、Codex 产品和错误库;它们已由协调者单独维护。",
|
|
44
|
+
"不得上传原始会话、个人路径、凭据或 Guard 私有控制材料,不把源测试宣称为原生验收。"
|
|
45
|
+
],
|
|
46
|
+
"validation": [],
|
|
47
|
+
"artifacts": [],
|
|
48
|
+
"pending_gates": [
|
|
49
|
+
"local_implementation",
|
|
50
|
+
"local_t01_t08",
|
|
51
|
+
"local_full_matrix",
|
|
52
|
+
"local_self_review",
|
|
53
|
+
"later_native_acceptance",
|
|
54
|
+
"later_release"
|
|
55
|
+
],
|
|
56
|
+
"actions_performed": [
|
|
57
|
+
"local_edit"
|
|
58
|
+
],
|
|
59
|
+
"limitations": [
|
|
60
|
+
"这是开发入口,不是已经实现的候选或发布许可;head_sha 表示现有基线,prepared_source_sha256 未冻结。",
|
|
61
|
+
"本交接 dirty_scope 是生成时的文档快照,接手必须核对实际变化;文档不得被当成远程已经存在。",
|
|
62
|
+
"later_native_acceptance 和 later_release 属于后续协调者,开发者本轮必须在这些步骤之前停止。"
|
|
63
|
+
],
|
|
64
|
+
"next_owner": "用户选择的 zcode 或 DSH 执行者(仅本地开发),完成后交回协调者"
|
|
65
|
+
}
|