dsh-completion-guard 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/CHANGELOG.zh-CN.md +18 -0
- package/README.md +15 -15
- package/README.zh-CN.md +15 -15
- package/bin/dsh-completion-guard-host-lock.mjs +13 -4
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.js +2 -2
- package/dist/{domain-DbPbaoXp.js → domain-Jo13xgPJ.js} +24727 -18610
- package/dist/{index-hiUtfKJa.d.ts → index-jKw6mANp.d.ts} +201 -129
- package/dist/index.d.ts +34 -3
- package/dist/index.js +613 -372
- package/docs/COMPATIBILITY.md +30 -42
- package/docs/DEVELOPMENT_PLAN_DSH_0_1_7_RC2.md +283 -0
- package/docs/DSH_0_1_7_RC2_ACCEPTANCE.md +57 -0
- package/docs/HISTORICAL_INCIDENT_COVERAGE.md +148 -0
- package/docs/HOST_LOCK_UPGRADE.md +55 -24
- package/docs/LOCAL_ACCEPTANCE.md +6 -2
- package/docs/PORTING_NOTES.md +5 -1
- package/docs/README.md +2 -0
- package/docs/THIRD_PARTY_LICENSES.md +27 -0
- package/docs/dsh-0.1.7-rc.2-planning-evidence.json +585 -0
- package/manifests/rc017-rc2-byte-audit.json +637 -0
- package/manifests/rc020-rc1-byte-audit.json +944 -0
- package/manifests/supported-host.v1.json +126 -1314
- package/package.json +41 -36
package/dist/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import {
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { $ as PROOF_KINDS, $i as hostVersionFromPackages, $n as capabilityConsequence, $r as statefulActionsOfScope, $t as reservationFor, A as PROTOCOL_V4_NOTICE, Aa as RC020_RC1_HOST_PACKAGES, Ai as HostTrustError, An as isCurrentAcceptedBoundary, Ar as interpretMessage, At as carriesCleanupCondition, B as extractToolSubject, Bi as BASE_HOST_PACKAGES, Bn as replayRebindResult, Br as legacyQuestionReadingIsInformational, Bt as sourceItemForCoreRequirement, C as SESSION_EVENT_ENVELOPE_INVALID, Ca as requestedIdentityKey, Ci as packageRowsFromPnpmLock, Cn as hasCurrentCertificate, Cr as clauseIsProtected, Ct as CLEANUP_CONDITION_RULE_COMPACT, D as CAPTURE_V042_NOTICE, Da as semanticActionFromText, Di as resolveActiveProfileHostLock, Dn as BOUNDARY_RECORD_PREFIX, Dr as hasQuestionScope, Dt as V6_ORDINARY_COMPLETION_RULE, E as projectCoreV2, Ea as semanticActionFromCommand, Ei as readActiveHostGraph, En as unitDescendantIds, Er as hasOrderedCoordination, Et as MIN_RECOVERY_CHAR_BUDGET, F as legacyRecordsNeedingReview, Fi as registryArchiveFiles, Fn as proposeRebind, Fr as isOpenObligation, Ft as recoveryTitle, G as isRunExecutable, Gi as HOST_COHORTS, Gn as deriveItemDiagnosis, Gr as opensWithDirective, Gt as inFlightReservation, H as persistedToolResultStatus, Hi as EXPECTED_HOST_PACKAGES, Hn as isFrozenV042RebindResponse, Hr as maskQuotedSpans, Ht as RELEASE_OPERATIONS, I as rootLocatorFlavor, Ii as registryArchiveModules, In as proposeRebindOutcome, Ir as isQuestionScopeNeedingReview, It as renderRecoveryPacket, J as authorityCaptureCounts, Ji as evaluateExternalWaitCapability, Jn as nativeFileTwoRole, Jr as questionHeadsClause, Jt as normalizeSettlement, K as parsePwshCommand, Ki as bindExecutableIdentity, Kn as evidenceAvailabilityReason, Kr as presentExplanationHead, Kt as normalizeReleaseContract, L as supersedeItem, Li as ACTIVE_HOST_COHORT_ID, Ln as proposeRebindV042, Lr as isRestatement, Lt as v6CurrentRootBoundaries, M as PROTOCOL_V6_NOTICE, Mi as hostTrustDigest, Mn as currentContractDigest, Mr as isExecutableItem, Mt as closingHint, N as applyUpgradeEligibility, Ni as parseHostTrust, Nn as createProjection, Nr as isExplanationScope, Nt as openItems, O as DEFAULT_DELEGATION_TOOL_NAMES, Oa as validateActionManifest, Oi as resolveInstalledHostLock, On as availableBoundaryQualifications, Or as hasWorkPredicate, Ot as V6_ORDINARY_COMPLETION_RULE_COMPACT, P as deriveProjection, Pi as qualifyHostTrust, Pn as confirmRebind, Pr as isInformationalFragment, Pt as recoveryDigest, Q as PROOF_CAPABILITY_MATRIX, Qi as evaluateToolSurfaceCapability, Qn as admissibleForRemoval, Qr as splitTextFragments, Qt as releasePreEffectDecision, R as evidenceFromPersistedToolResult, Ri as ACTIVE_HOST_COHORT_IDS, Rn as rebindAttemptKey, Rr as itemHoldsExecutionAuthority, Rt as currentV6Feedback, S as SESSION_API_UNSUPPORTED, Sa as isStatefulAction, Si as packageRowsFromActiveGraph, Sn as goalCompletionDenial, Sr as clauseIsGoverned, St as CLEANUP_CONDITION_RULE, T as snapshotSessionEvents, Ta as requestedTargetMatchesResolved, Ti as prepareTargetHostTrust, Tn as certificateClosure, Tr as governedClauseRestrictsExecution, Tt as DEFAULT_RECOVERY_CHAR_BUDGET, U as withDurability, Ui as GOAL_HOST_PACKAGES, Un as parseConfirmationMessage, Ur as namedActions, Ut as RELEASE_OPERATION_SURFACES, V as isDeterministicCheck, Vi as DEFAULT_HOST_LOCK, Vn as CONFIRM_LINE_PATTERN, Vr as maskCodeSpans, Vt as OUTCOME_STRENGTH, W as canonicalArgvFromCommand, Wi as HOST_CAPABILITY_PACKAGE_GROUPS, Wn as capabilityRemedyPhrase, Wr as opensConditionLead, Wt as contractById, X as bindingIndividuallyAccepted, Xi as evaluateHostCapability, Xn as DEPENDENCY_FREE_ONLY_CONDITION, Xr as restatedContentOf, Xt as releaseContractFor, Y as segmentAuthorityBlocks, Yi as evaluateGraphDerivedHostLock, Yn as relevantEvidence, Yr as reportingHeadGoverns, Yt as readbackSettlesContract, Z as certifyCheckpoint, Zi as evaluateHostLock, Zn as actionHasCertificationPath, Zr as semanticActionOfScope, Zt as releaseCoverage, _ as projectSessionCoreV2, _a as STOP_PROTOCOL_VERSION, _i as evaluateConfiguredHostLock, _n as latestRootInstruction, _r as GRANTED_QUALIFICATION, _t as scopeCoverageDigest, a as createGitPrestateEnvelope, aa as SUPPORTED_HOST_VERSIONS, ai as normalizeClause, an as NO_PROGRESS_RECORD_PREFIX, ar as captureItem, at as bindProofV2ToProjection, b as captureHostWorkdir, ba as actionCompatible, bi as injectActiveProfileHostLock, bn as testOutcomePredicate, br as clarifiedSpanOf, bt as validateProofManifest, c as parseGitCommandManifest, ca as parseHostVersion, ci as sha256, cn as assessmentOutcomePredicate, cr as extractArtifactPaths, ct as createProofManifestV2, d as FIRST_STEP_GUIDANCE, da as ACTION_MANIFEST_VERSION, di as auditedDefaultWorkdirHost, dn as decideTurnBoundary, dr as isInformationalMessage, dt as proofDigestV2, ea as selectHostCohort, ei as verbIsNegated, en as bindingSatisfies, er as capabilityFactOf, et as PROOF_KINDS_V2, f as claimedBatchHasRealRootInput, fa as BOUNDED_ARTIFACT_TYPES, fi as auditedDefaultWorkdirProvider, fn as decideTurnStopping, fr as segmentClauses, ft as proofEvidenceConstraints, g as previewFirstStepInjection, ga as STATEFUL_ACTIONS, gi as evaluateActiveHostLock, gn as latestAssistantText, gr as classifyUserInteraction, gt as requiredSubjectsOf, h as lifecyclePhase, ha as SEMANTIC_ACTIONS, hi as combineHostPolicy, hn as isWholeTaskCompletionClaim, hr as classifyTaskIntent, ht as proofV2Rejection, i as commitTreeSnapshotDigest, ia as SUPPORTED_HOST_RANGE, ii as digestStrings, in as CONTROL_RECORD_PREFIX, ir as captureClause, it as bindProofToProjection, j as PROTOCOL_V5_NOTICE, ja as createHostAuditSession, ji as acquireHostTrust, jn as qualifyBoundary, jr as introducesActionClause, jt as cleanupConditionFor, k as PROTOCOL_V3_NOTICE, ka as validateActionTarget, ki as verifyComposedHostLockDump, kn as effectuateBoundary, kr as interpretClause, kt as V6_ORDINARY_COMPLETION_RULE_SHORT, l as revalidateGitPrestate, la as satisfiesSupportedHostRange, li as HostProfileError, ln as classifyCompletionClaim, lr as extractMethod, lt as proofCapabilityReport, m as firstStepGuidanceV6, ma as CERTIFICATE_VERSION_V2, mi as auditedHostImplementation, mn as isRootPauseRequest, mr as npmEscapedPackageName, mt as proofOperationMatches, n as GIT_COMMAND_TEMPLATES, na as LATEST_TESTED_HOST_VERSION, ni as validateManifest, nn as evidenceMatchesItem, nr as removalIsComplete, nt as PROOF_PROTOCOL_VERSION, o as executeRevalidatedGitEffect, oa as compareHostVersions, oi as sanitizeClauseText, on as NO_PROGRESS_TURNS_BEFORE_STOP, or as classifyClause, ot as canonicalProjection, p as firstStepGuidance, pa as CERTIFICATE_VERSION, pi as auditedForegroundRenderers, pn as decisionBoundaryKey, pr as canonicalRegistryBase, pt as proofHostSurfacesOf, q as parseShellCommand, qi as bindLiveGoalCapability, qn as itemDiagnosis, qr as qualificationOfClause, qt as normalizeReservation, r as commitIndexSnapshotDigest, ra as MIN_SUPPORTED_HOST_VERSION, ri as canonicalizePath, rn as isVerifyingCapability, rr as removalIsPartiallyKnown, rt as PROOF_PROTOCOL_VERSION_V2, s as gitCommandMatchesTarget, sa as evaluateMinimumHostVersion, si as sanitizeUrl, sn as assessmentAction, sr as environmentDefaultRepositoryTarget, st as createProofManifest, t as GIT_COMMAND_MANIFEST_IDS, ta as HOST_VALIDATED_VERSIONS, ti as COMMAND_SURFACE_MANIFEST, tn as evidenceCoverage, tr as partialFailureOf, tt as PROOF_MANIFEST_DOMAIN_V2, u as verifiedLinearCommitReadback, ua as ACTION_MANIFEST, ui as activeRendererModule, un as currentActionBases, ur as extractOperation, ut as proofDigest, v as sessionCoreSnapshot, va as STOP_PROTOCOL_VERSION_V2, vi as hostLockContextFromComposedDump, vn as observeAssistantOutcome, vr as LEGACY_QUALIFICATION, vt as sessionQuery, w as SessionApiError, wa as requestedTargetAuthorizesMutation, wi as prepareActiveHostTrust, wn as certifiableOpenItems, wr as explanationHasActionResidue, wt as CLEANUP_CONDITION_RULE_SHORT, x as sourcedNamedTestRoot, xa as boundedArtifactChoiceMatches, xi as inspectTargetHostGraph, xn as v6TestPredicate, xr as clauseAsksOwnQuestion, xt as validateProofManifestV2, y as HOST_WORKDIR_PREFIX, ya as SUPPORTED_EVIDENCE_ADAPTERS, yi as hostLockRowsFromComposedDump, yn as progressFingerprint, yr as actionVerbMatches, yt as sessionQueryV2, z as extractTextContent, zi as ACTIVE_HOST_LAUNCHER_VERSION, zn as rebindResponse, zr as kindOfScope, zt as isV6PendingRootWait } from "./domain-Jo13xgPJ.js";
|
|
2
|
+
import { boundContextSummary, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
4
3
|
import { basename, delimiter, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
7
6
|
import { closeSync, constants, existsSync, fchmodSync, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, unlinkSync, writeSync } from "node:fs";
|
|
8
|
-
import {
|
|
7
|
+
import { gunzip } from "node:zlib";
|
|
9
8
|
import { execFile } from "node:child_process";
|
|
9
|
+
import { homedir, tmpdir } from "node:os";
|
|
10
|
+
import { JobId } from "@deepseek-ai/dsh-jobs";
|
|
11
|
+
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
12
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
13
|
+
import { promisify } from "node:util";
|
|
10
14
|
import { access, readFile, realpath } from "node:fs/promises";
|
|
11
|
-
import { fileURLToPath } from "node:url";
|
|
12
|
-
import { gunzip } from "node:zlib";
|
|
13
15
|
import { SESSION_FORMAT_VERSION, Session, SessionId } from "@deepseek-ai/dsh-session";
|
|
14
16
|
|
|
15
17
|
//#region src/tools/rebind.ts
|
|
@@ -62,6 +64,18 @@ function createRebindTool(getProjection, prepare) {
|
|
|
62
64
|
});
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/tools/cursor-identity.ts
|
|
69
|
+
/** The Session observation watermark advances when a read-only Guard tool
|
|
70
|
+
* records its own result. It is not a change to the current business state.
|
|
71
|
+
* Keep every other core field in cursor identity so changed predicates,
|
|
72
|
+
* actions, coverage, and release state still invalidate a page. */
|
|
73
|
+
function semanticCoreCursorState(core) {
|
|
74
|
+
if (!core) return null;
|
|
75
|
+
const { as_of: _observationWatermark,...semantic } = core;
|
|
76
|
+
return semantic;
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
//#endregion
|
|
66
80
|
//#region src/tools/checkpoint-page.ts
|
|
67
81
|
const LANES = [
|
|
@@ -86,7 +100,7 @@ function checkpointPage(p, query, full) {
|
|
|
86
100
|
revision: p.contractRevision,
|
|
87
101
|
evidence: [...p.evidence.values()],
|
|
88
102
|
items: [...p.items.values()],
|
|
89
|
-
...full.current_feedback === true ? { current_core: p.coreV2 } : {},
|
|
103
|
+
...full.current_feedback === true ? { current_core: semanticCoreCursorState(p.coreV2) } : {},
|
|
90
104
|
item_ids,
|
|
91
105
|
evidence_ids,
|
|
92
106
|
evidence_scope,
|
|
@@ -292,38 +306,70 @@ function bindingTemplate(projection, item) {
|
|
|
292
306
|
const action = item.semanticAction;
|
|
293
307
|
if (!action || action === "generic_run") return void 0;
|
|
294
308
|
const evidence = evidenceForAction(projection, item);
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
resolution.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
309
|
+
const effects = evidence.filter((entry) => (entry.evidenceRole ?? "effect") === "effect");
|
|
310
|
+
for (const effect of effects.reverse()) {
|
|
311
|
+
if (!effect.resolvedTarget) continue;
|
|
312
|
+
const resolved = effect.resolvedTarget;
|
|
313
|
+
const nativeFile = projection.boundaryProtocol === 6 && action === "modify" && !item.legacyFlags?.length && ["edit", "edit_file"].includes(effect.toolName);
|
|
314
|
+
const states = nativeFile ? evidence.filter((entry) => entry.evidenceRole === "state" && entry.causedByCallId === effect.callId) : isStatefulAction(action) ? evidence.filter((entry) => entry.evidenceRole === "state" && sameTuple(entry.resolvedTarget, resolved)) : [];
|
|
315
|
+
const resolution = !nativeFile && isStatefulAction(action) ? evidence.find((entry) => entry.evidenceRole === "resolution" && sameTuple(entry.resolvedTarget, resolved)) : void 0;
|
|
316
|
+
if (isStatefulAction(action) && !nativeFile && (!resolution || states.length === 0 || !resolution.expectedTransition?.parameters || !resolution.expectedTransitionDigest)) continue;
|
|
317
|
+
const candidates = nativeFile ? states.map((state) => [state]) : [states];
|
|
318
|
+
for (const chosen of candidates) {
|
|
319
|
+
if (nativeFile && chosen.length !== 1) continue;
|
|
320
|
+
const observed = nativeFile ? { post_digest: chosen[0]?.observedState?.post_digest ?? "" } : isStatefulAction(action) ? Object.assign({}, ...chosen.map((entry) => entry.observedState ?? {})) : effect.observedState ?? {};
|
|
321
|
+
const expectedTransition = nativeFile ? {
|
|
322
|
+
predicateId: ACTION_MANIFEST.actions[action].predicateId,
|
|
323
|
+
version: 1,
|
|
324
|
+
predParamsKind: "inline",
|
|
325
|
+
parameters: observed
|
|
326
|
+
} : isStatefulAction(action) ? resolution.expectedTransition : {
|
|
327
|
+
predicateId: ACTION_MANIFEST.actions[action].predicateId,
|
|
328
|
+
version: 1,
|
|
329
|
+
predParamsKind: "inline",
|
|
330
|
+
parameters: expectedParameters(action, resolved, observed)
|
|
331
|
+
};
|
|
332
|
+
const binding = {
|
|
333
|
+
itemId: item.id,
|
|
334
|
+
evidenceIds: nativeFile ? [effect.id, chosen[0].id] : isStatefulAction(action) ? [
|
|
335
|
+
resolution.id,
|
|
336
|
+
effect.id,
|
|
337
|
+
...chosen.map((entry) => entry.id)
|
|
338
|
+
] : [effect.id],
|
|
339
|
+
semanticAction: action,
|
|
340
|
+
requestedTarget: item.requestedTarget,
|
|
341
|
+
resolvedTarget: resolved,
|
|
342
|
+
observedState: observed,
|
|
343
|
+
expectedTransition,
|
|
344
|
+
...nativeFile ? {
|
|
345
|
+
effectEvidenceId: effect.id,
|
|
346
|
+
stateEvidenceIds: [chosen[0].id]
|
|
347
|
+
} : isStatefulAction(action) ? {
|
|
348
|
+
resolutionEvidenceId: resolution.id,
|
|
349
|
+
effectEvidenceId: effect.id,
|
|
350
|
+
stateEvidenceIds: chosen.map((entry) => entry.id)
|
|
351
|
+
} : { effectEvidenceId: effect.id }
|
|
352
|
+
};
|
|
353
|
+
if (!bindingIndividuallyAccepted(projection, item, binding)) continue;
|
|
354
|
+
return {
|
|
355
|
+
item_id: item.id,
|
|
356
|
+
evidence_ids: binding.evidenceIds,
|
|
357
|
+
semantic_action: action,
|
|
358
|
+
requested_target: targetForTool(item.requestedTarget),
|
|
359
|
+
resolved_target: targetForTool(resolved),
|
|
360
|
+
observed_state: targetForTool(observed),
|
|
361
|
+
expected_transition: expectedTransitionForTool(expectedTransition),
|
|
362
|
+
...nativeFile ? {
|
|
363
|
+
effect_evidence_id: effect.id,
|
|
364
|
+
state_evidence_ids: [chosen[0].id]
|
|
365
|
+
} : isStatefulAction(action) ? {
|
|
366
|
+
resolution_evidence_id: resolution.id,
|
|
367
|
+
effect_evidence_id: effect.id,
|
|
368
|
+
state_evidence_ids: chosen.map((entry) => entry.id)
|
|
369
|
+
} : { effect_evidence_id: effect.id }
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
327
373
|
}
|
|
328
374
|
function openItemForTool(projection, item) {
|
|
329
375
|
const action = item.semanticAction ?? "generic_run";
|
|
@@ -357,7 +403,7 @@ function openItemForTool(projection, item) {
|
|
|
357
403
|
predicate: {
|
|
358
404
|
predicate_id: spec.predicateId,
|
|
359
405
|
version: 1,
|
|
360
|
-
parameters_source: isStatefulAction(action) ? "resolution_evidence_expected_transition" : "versioned_action_manifest",
|
|
406
|
+
parameters_source: nativeFileTwoRole(projection, item) ? "native_state_readback" : isStatefulAction(action) ? "resolution_evidence_expected_transition" : "versioned_action_manifest",
|
|
361
407
|
resolved_target_keys: spec.resolvedTargetKeys,
|
|
362
408
|
observed_state_keys: spec.observedStateKeys,
|
|
363
409
|
pred_params_kind: "inline"
|
|
@@ -365,7 +411,7 @@ function openItemForTool(projection, item) {
|
|
|
365
411
|
...template ? { binding_template: template } : {}
|
|
366
412
|
};
|
|
367
413
|
}
|
|
368
|
-
function createCheckpointTool(getProjection, onRejected, prepare = async () => true) {
|
|
414
|
+
function createCheckpointTool(getProjection, onRejected, prepare = async () => true, revalidate = () => {}) {
|
|
369
415
|
return defineTool({
|
|
370
416
|
name: "context_guard_checkpoint",
|
|
371
417
|
description: "Read current ordinary closure from confirmed observations; request a certificate only for an explicitly adopted proof, Goal, or release contract.",
|
|
@@ -791,6 +837,7 @@ function createCheckpointTool(getProjection, onRejected, prepare = async () => t
|
|
|
791
837
|
order: closure.order
|
|
792
838
|
})) } : {}
|
|
793
839
|
}));
|
|
840
|
+
revalidate();
|
|
794
841
|
let proofState = {
|
|
795
842
|
status: "absent",
|
|
796
843
|
reason_codes: []
|
|
@@ -1495,7 +1542,6 @@ function createPrepareTool(options) {
|
|
|
1495
1542
|
}
|
|
1496
1543
|
if (args.item_id === void 0) {
|
|
1497
1544
|
const filter = args.semantic_action ?? null;
|
|
1498
|
-
const coreIdentity = currentFeedback ? sha256(JSON.stringify(p.coreV2 ?? null)) : void 0;
|
|
1499
1545
|
const invalidCursor = (reason_code, note) => ({
|
|
1500
1546
|
status: "rejected",
|
|
1501
1547
|
reason_code,
|
|
@@ -1503,6 +1549,15 @@ function createPrepareTool(options) {
|
|
|
1503
1549
|
contract_revision: p.contractRevision,
|
|
1504
1550
|
...note !== void 0 ? { note } : { note: "Re-run discovery without page_cursor to list from the first page." }
|
|
1505
1551
|
});
|
|
1552
|
+
const eligible = discoveryItemIds(p).map((id) => ({
|
|
1553
|
+
id,
|
|
1554
|
+
sourced: currentFeedback ? sourceItemForCoreRequirement(p, id) : void 0,
|
|
1555
|
+
item: currentFeedback ? sourceItemForCoreRequirement(p, id)?.item : p.items.get(id)
|
|
1556
|
+
})).filter((entry) => entry.item !== void 0).filter(({ item: item$1, sourced }) => filter === null || (sourced?.origin?.action ?? item$1.semanticAction ?? "generic_run") === filter);
|
|
1557
|
+
const coreIdentity = currentFeedback ? sha256(JSON.stringify({
|
|
1558
|
+
core: semanticCoreCursorState(p.coreV2),
|
|
1559
|
+
listing: eligible.map(({ id, item: item$1 }) => [id, item$1.revision])
|
|
1560
|
+
})) : void 0;
|
|
1506
1561
|
let startAfter;
|
|
1507
1562
|
if (args.page_cursor !== void 0) {
|
|
1508
1563
|
let parsed;
|
|
@@ -1520,11 +1575,6 @@ function createPrepareTool(options) {
|
|
|
1520
1575
|
if ((parsed.f ?? null) !== (filter ?? null)) return invalidCursor("discovery_cursor_filter_mismatch");
|
|
1521
1576
|
startAfter = parsed.k;
|
|
1522
1577
|
}
|
|
1523
|
-
const eligible = discoveryItemIds(p).map((id) => ({
|
|
1524
|
-
id,
|
|
1525
|
-
sourced: currentFeedback ? sourceItemForCoreRequirement(p, id) : void 0,
|
|
1526
|
-
item: currentFeedback ? sourceItemForCoreRequirement(p, id)?.item : p.items.get(id)
|
|
1527
|
-
})).filter((entry) => entry.item !== void 0).filter(({ item: item$1, sourced }) => filter === null || (sourced?.origin?.action ?? item$1.semanticAction ?? "generic_run") === filter);
|
|
1528
1578
|
const startIndex = startAfter === void 0 ? 0 : eligible.findIndex(({ id, item: item$1 }) => item$1.revision === startAfter[0] && id === startAfter[1]) + 1;
|
|
1529
1579
|
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.");
|
|
1530
1580
|
const page = eligible.slice(startIndex, startIndex + DISCOVERY_ITEM_LIMIT);
|
|
@@ -1654,7 +1704,7 @@ function createPrepareTool(options) {
|
|
|
1654
1704
|
resolved_target: evidence.resolvedTarget,
|
|
1655
1705
|
tool_result_seq: evidence.toolResultSeq
|
|
1656
1706
|
}));
|
|
1657
|
-
const requiredOrder = plannedAction && isStatefulAction(plannedAction) ? [
|
|
1707
|
+
const requiredOrder = nativeFileTwoRole(p, item) ? ["effect (the persisted native edit result)", "state (independent context_guard_observe_file readback)"] : plannedAction && isStatefulAction(plannedAction) ? [
|
|
1658
1708
|
"resolution (prestate facts from a trusted read)",
|
|
1659
1709
|
"effect (the exact planned change)",
|
|
1660
1710
|
"state (independent post-state readback)"
|
|
@@ -1867,7 +1917,7 @@ function restartIntent(events, resolutionCallId, target) {
|
|
|
1867
1917
|
if (!event || event.type !== "user/message") continue;
|
|
1868
1918
|
const data = record$1(event.data);
|
|
1869
1919
|
const source = record$1(data?.source);
|
|
1870
|
-
if (source?.kind !== "plugin" || source.plugin !== "context-guard" || source.form !== "notice") continue;
|
|
1920
|
+
if (source?.kind !== "plugin" && source?.kind !== "context-guard" || source.plugin !== "context-guard" || source.form !== "notice") continue;
|
|
1871
1921
|
const content = Array.isArray(data?.content) ? data.content : [];
|
|
1872
1922
|
const block = content.length === 1 ? record$1(content[0]) : void 0;
|
|
1873
1923
|
const text = typeof block?.text === "string" ? block.text : "";
|
|
@@ -2439,6 +2489,10 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
|
|
|
2439
2489
|
const tgzPath = requireString(resolution.commandManifest, "tgz_path");
|
|
2440
2490
|
const identity = tgzPath ? await tgzIdentity(tgzPath) : void 0;
|
|
2441
2491
|
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" };
|
|
2492
|
+
if (roots.preEffectVeto?.() === false) return {
|
|
2493
|
+
status: "unavailable",
|
|
2494
|
+
reasonCode: "pre_effect_host_veto_refused"
|
|
2495
|
+
};
|
|
2442
2496
|
await runCommand(roots, executableIdentity$1, [
|
|
2443
2497
|
"plugin",
|
|
2444
2498
|
"--profile",
|
|
@@ -2453,6 +2507,10 @@ async function executeGuardAction(action, resolution, roots, signal, executableI
|
|
|
2453
2507
|
const identity = tgzPath ? await tgzIdentity(tgzPath) : void 0;
|
|
2454
2508
|
const registry = typeof target.registry === "string" ? canonicalRegistryBase(target.registry, { allowLoopbackHttp: roots.allowLoopbackHttpRegistry }) : void 0;
|
|
2455
2509
|
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" };
|
|
2510
|
+
if (roots.preEffectVeto?.() === false) return {
|
|
2511
|
+
status: "unavailable",
|
|
2512
|
+
reasonCode: "pre_effect_host_veto_refused"
|
|
2513
|
+
};
|
|
2456
2514
|
await runCommand(roots, executableIdentity$1, [
|
|
2457
2515
|
"publish",
|
|
2458
2516
|
tgzPath,
|
|
@@ -2977,7 +3035,8 @@ function normalizedRoots(options) {
|
|
|
2977
3035
|
...options.readExecutableIdentity ? { readExecutableIdentity: options.readExecutableIdentity } : {},
|
|
2978
3036
|
...options.allowLoopbackHttpRegistry ? { allowLoopbackHttpRegistry: true } : {},
|
|
2979
3037
|
...options.releaseGate ? { releaseGate: options.releaseGate } : {},
|
|
2980
|
-
...options.releaseSettle ? { releaseSettle: options.releaseSettle } : {}
|
|
3038
|
+
...options.releaseSettle ? { releaseSettle: options.releaseSettle } : {},
|
|
3039
|
+
...options.preEffectVeto ? { preEffectVeto: options.preEffectVeto } : {}
|
|
2981
3040
|
};
|
|
2982
3041
|
}
|
|
2983
3042
|
function createActionTool(options = {}) {
|
|
@@ -3091,11 +3150,6 @@ function createActionTool(options = {}) {
|
|
|
3091
3150
|
reason_code: "action_adapter_unavailable",
|
|
3092
3151
|
...empty
|
|
3093
3152
|
};
|
|
3094
|
-
if (roots.hostCapability?.(action).status !== "supported" && roots.hostCapability) return {
|
|
3095
|
-
status: "unavailable",
|
|
3096
|
-
reason_code: "host_capability_unavailable",
|
|
3097
|
-
...empty
|
|
3098
|
-
};
|
|
3099
3153
|
let durable = false;
|
|
3100
3154
|
try {
|
|
3101
3155
|
durable = await roots.prepareMutation?.(agent) === true;
|
|
@@ -3125,6 +3179,31 @@ function createActionTool(options = {}) {
|
|
|
3125
3179
|
reason_code: "target_digest_mismatch",
|
|
3126
3180
|
...identity
|
|
3127
3181
|
};
|
|
3182
|
+
const executable = executableFor(action);
|
|
3183
|
+
let currentExecutable;
|
|
3184
|
+
if (executable) {
|
|
3185
|
+
currentExecutable = await (roots.readExecutableIdentity ?? executableIdentity)(executable, exec.signal);
|
|
3186
|
+
if (bindExecutableIdentity(resolution.executableIdentity, currentExecutable).status !== "supported") return {
|
|
3187
|
+
status: "unavailable",
|
|
3188
|
+
reason_code: "executable_identity_drift",
|
|
3189
|
+
...identity
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
const releaseOperation = action === "publish" ? "npm_publish" : void 0;
|
|
3193
|
+
let observed;
|
|
3194
|
+
if (releaseOperation && roots.releaseGate) {
|
|
3195
|
+
observed = await observePublishCandidate(resolution, roots, exec.signal, cwdOf(agent));
|
|
3196
|
+
if (!observed) return {
|
|
3197
|
+
status: "unavailable",
|
|
3198
|
+
reason_code: "release_candidate_unobservable",
|
|
3199
|
+
...identity
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3202
|
+
if (roots.hostCapability?.(action).status !== "supported" && roots.hostCapability) return {
|
|
3203
|
+
status: "unavailable",
|
|
3204
|
+
reason_code: "host_capability_unavailable",
|
|
3205
|
+
...empty
|
|
3206
|
+
};
|
|
3128
3207
|
let authorization;
|
|
3129
3208
|
try {
|
|
3130
3209
|
authorization = roots.authorizeMutation?.({
|
|
@@ -3141,26 +3220,9 @@ function createActionTool(options = {}) {
|
|
|
3141
3220
|
reason_code: authorization?.reasonCode ?? "mutation_authority_unavailable",
|
|
3142
3221
|
...identity
|
|
3143
3222
|
};
|
|
3144
|
-
const executable = executableFor(action);
|
|
3145
|
-
let currentExecutable;
|
|
3146
|
-
if (executable) {
|
|
3147
|
-
currentExecutable = await (roots.readExecutableIdentity ?? executableIdentity)(executable, exec.signal);
|
|
3148
|
-
if (bindExecutableIdentity(resolution.executableIdentity, currentExecutable).status !== "supported") return {
|
|
3149
|
-
status: "unavailable",
|
|
3150
|
-
reason_code: "executable_identity_drift",
|
|
3151
|
-
...identity
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
const releaseOperation = action === "publish" ? "npm_publish" : void 0;
|
|
3155
3223
|
let releaseGranted = false;
|
|
3156
3224
|
let releaseContractId;
|
|
3157
3225
|
if (releaseOperation && roots.releaseGate) {
|
|
3158
|
-
const observed = await observePublishCandidate(resolution, roots, exec.signal, cwdOf(agent));
|
|
3159
|
-
if (!observed) return {
|
|
3160
|
-
status: "unavailable",
|
|
3161
|
-
reason_code: "release_candidate_unobservable",
|
|
3162
|
-
...identity
|
|
3163
|
-
};
|
|
3164
3226
|
let decision;
|
|
3165
3227
|
try {
|
|
3166
3228
|
decision = await roots.releaseGate({
|
|
@@ -4245,12 +4307,12 @@ function createExternalOperationTool(read, capability) {
|
|
|
4245
4307
|
reason_code: "host_jobs_capability_unavailable",
|
|
4246
4308
|
adapter_id: "dsh.jobs.v1"
|
|
4247
4309
|
});
|
|
4248
|
-
const snapshot = read(args.operation_id, exec.agent);
|
|
4249
|
-
return Promise.resolve(snapshot ? {
|
|
4250
|
-
status: snapshot.status,
|
|
4251
|
-
operation_id: snapshot.id,
|
|
4310
|
+
const snapshot$1 = read(args.operation_id, exec.agent);
|
|
4311
|
+
return Promise.resolve(snapshot$1 ? {
|
|
4312
|
+
status: snapshot$1.status,
|
|
4313
|
+
operation_id: snapshot$1.id,
|
|
4252
4314
|
reason_code: "external_operation_readback",
|
|
4253
|
-
adapter_id: snapshot.adapterId
|
|
4315
|
+
adapter_id: snapshot$1.adapterId
|
|
4254
4316
|
} : {
|
|
4255
4317
|
status: "unknown",
|
|
4256
4318
|
operation_id: args.operation_id,
|
|
@@ -4536,7 +4598,7 @@ function createContextGuardCommand(projectionFor, setEnabled, clearContract, lif
|
|
|
4536
4598
|
}
|
|
4537
4599
|
|
|
4538
4600
|
//#endregion
|
|
4539
|
-
//#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.
|
|
4601
|
+
//#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.5/node_modules/@deepseek-ai/cosmokit/lib/index.js
|
|
4540
4602
|
/** Return true when a value is `null` or `undefined`. */
|
|
4541
4603
|
function isNullable(value) {
|
|
4542
4604
|
return value === null || value === void 0;
|
|
@@ -4560,6 +4622,43 @@ function pick(source, keys, forced) {
|
|
|
4560
4622
|
for (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];
|
|
4561
4623
|
return result;
|
|
4562
4624
|
}
|
|
4625
|
+
/** Shared config references used by schema validators and plugin runtimes. */
|
|
4626
|
+
const write = Symbol.for("cosmokit.volatile.write");
|
|
4627
|
+
function snapshot(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
4628
|
+
if (typeof value === "function") throw new TypeError("volatile config cannot contain functions");
|
|
4629
|
+
if (value === null || typeof value !== "object") return value;
|
|
4630
|
+
if (ancestors.has(value)) throw new TypeError("volatile config cannot contain cycles");
|
|
4631
|
+
ancestors.add(value);
|
|
4632
|
+
try {
|
|
4633
|
+
if (Array.isArray(value)) return Object.freeze(value.map((item) => snapshot(item, ancestors)));
|
|
4634
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new TypeError("volatile config objects must be plain objects or arrays");
|
|
4635
|
+
return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, snapshot(item, ancestors)])));
|
|
4636
|
+
} finally {
|
|
4637
|
+
ancestors.delete(value);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
/**
|
|
4641
|
+
* Create a detached reference containing an immutable copy of the supplied data.
|
|
4642
|
+
* @param value - validated config data; class instances and functions are unsupported.
|
|
4643
|
+
* @returns a reference whose value is updated only by its owning runtime.
|
|
4644
|
+
*/
|
|
4645
|
+
function createVolatile(value) {
|
|
4646
|
+
let current = snapshot(value);
|
|
4647
|
+
return Object.freeze({
|
|
4648
|
+
get: () => current,
|
|
4649
|
+
[write]: (value$1) => {
|
|
4650
|
+
current = value$1;
|
|
4651
|
+
}
|
|
4652
|
+
});
|
|
4653
|
+
}
|
|
4654
|
+
/**
|
|
4655
|
+
* Identify references across ESM/CJS copies of the shared library.
|
|
4656
|
+
* @param value - a parsed config value.
|
|
4657
|
+
* @returns whether the value implements the shared reference protocol.
|
|
4658
|
+
*/
|
|
4659
|
+
function isVolatile(value) {
|
|
4660
|
+
return typeof value === "object" && value !== null && write in value;
|
|
4661
|
+
}
|
|
4563
4662
|
/** Test values using `instanceof` with a `toStringTag` fallback. */
|
|
4564
4663
|
function is(type, value) {
|
|
4565
4664
|
if (arguments.length === 1) return (value$1) => is(type, value$1);
|
|
@@ -4644,26 +4743,47 @@ function clone(source, refs = /* @__PURE__ */ new Map()) {
|
|
|
4644
4743
|
}
|
|
4645
4744
|
return result;
|
|
4646
4745
|
}
|
|
4647
|
-
/**
|
|
4746
|
+
/**
|
|
4747
|
+
* Compare values recursively, treating two volatile references as equal regardless of value.
|
|
4748
|
+
* Strict comparison distinguishes null/undefined, treats opaque objects by identity,
|
|
4749
|
+
* compares URLs by normalized href, treats array holes as undefined, and considers distinct cyclic structures unequal.
|
|
4750
|
+
* @param a - first value.
|
|
4751
|
+
* @param b - second value.
|
|
4752
|
+
* @param strict - whether to require strict data equality outside volatile references.
|
|
4753
|
+
* @returns whether the values compare equal.
|
|
4754
|
+
*/
|
|
4648
4755
|
function deepEqual(a, b, strict) {
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4756
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
4757
|
+
function compare(a$1, b$1) {
|
|
4758
|
+
if (a$1 === b$1) return true;
|
|
4759
|
+
if (isVolatile(a$1) || isVolatile(b$1)) return isVolatile(a$1) && isVolatile(b$1);
|
|
4760
|
+
if (!strict && isNullable(a$1) && isNullable(b$1)) return true;
|
|
4761
|
+
if (typeof a$1 !== typeof b$1 || typeof a$1 !== "object" || !a$1 || !b$1) return false;
|
|
4762
|
+
if (ancestors.has(a$1)) return false;
|
|
4763
|
+
function check(test, then) {
|
|
4764
|
+
return test(a$1) ? test(b$1) ? then(a$1, b$1) : false : test(b$1) ? false : void 0;
|
|
4765
|
+
}
|
|
4766
|
+
ancestors.add(a$1);
|
|
4767
|
+
try {
|
|
4768
|
+
return check(Array.isArray, (a$2, b$2) => {
|
|
4769
|
+
if (a$2.length !== b$2.length) return false;
|
|
4770
|
+
for (let index = 0; index < a$2.length; index++) if (!compare(a$2[index], b$2[index])) return false;
|
|
4771
|
+
return true;
|
|
4772
|
+
}) ?? check(is("Date"), (a$2, b$2) => a$2.valueOf() === b$2.valueOf()) ?? check(is("URL"), (a$2, b$2) => a$2.href === b$2.href) ?? check(is("RegExp"), (a$2, b$2) => a$2.source === b$2.source && a$2.flags === b$2.flags) ?? check(isArrayBufferLike, (a$2, b$2) => {
|
|
4773
|
+
if (a$2.byteLength !== b$2.byteLength) return false;
|
|
4774
|
+
const viewA = new Uint8Array(a$2);
|
|
4775
|
+
const viewB = new Uint8Array(b$2);
|
|
4776
|
+
for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
|
|
4777
|
+
return true;
|
|
4778
|
+
}) ?? ((!strict || [a$1, b$1].every((value) => Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) && Object.keys({
|
|
4779
|
+
...a$1,
|
|
4780
|
+
...b$1
|
|
4781
|
+
}).every((key) => compare(a$1[key], b$1[key])));
|
|
4782
|
+
} finally {
|
|
4783
|
+
ancestors.delete(a$1);
|
|
4784
|
+
}
|
|
4656
4785
|
}
|
|
4657
|
-
return
|
|
4658
|
-
if (a$1.byteLength !== b$1.byteLength) return false;
|
|
4659
|
-
const viewA = new Uint8Array(a$1);
|
|
4660
|
-
const viewB = new Uint8Array(b$1);
|
|
4661
|
-
for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
|
|
4662
|
-
return true;
|
|
4663
|
-
}) ?? Object.keys({
|
|
4664
|
-
...a,
|
|
4665
|
-
...b
|
|
4666
|
-
}).every((key) => deepEqual(a[key], b[key], strict));
|
|
4786
|
+
return compare(a, b);
|
|
4667
4787
|
}
|
|
4668
4788
|
/** Time constants plus parsing and formatting helpers. */
|
|
4669
4789
|
var Time;
|
|
@@ -4737,7 +4857,7 @@ var Time;
|
|
|
4737
4857
|
})(Time || (Time = {}));
|
|
4738
4858
|
|
|
4739
4859
|
//#endregion
|
|
4740
|
-
//#region node_modules/.pnpm/@deepseek-ai+schemastery@3.18.
|
|
4860
|
+
//#region node_modules/.pnpm/@deepseek-ai+schemastery@3.18.4/node_modules/@deepseek-ai/schemastery/lib/index.mjs
|
|
4741
4861
|
const kSchema = Symbol.for("schemastery");
|
|
4742
4862
|
const kValidationError = Symbol.for("ValidationError");
|
|
4743
4863
|
globalThis.__schemastery_index__ ??= 0;
|
|
@@ -4913,6 +5033,7 @@ Schema.prototype.pattern = function pattern(regexp) {
|
|
|
4913
5033
|
return schema;
|
|
4914
5034
|
};
|
|
4915
5035
|
Schema.prototype.simplify = function simplify(value) {
|
|
5036
|
+
if (isVolatile(value)) value = value.get();
|
|
4916
5037
|
if (deepEqual(value, this.meta.default, this.type === "dict")) return null;
|
|
4917
5038
|
if (isNullable(value)) return value;
|
|
4918
5039
|
if (this.type === "object" || this.type === "dict") {
|
|
@@ -4969,12 +5090,49 @@ for (const key of [
|
|
|
4969
5090
|
};
|
|
4970
5091
|
return schema;
|
|
4971
5092
|
} });
|
|
5093
|
+
Schema.prototype.volatile = function volatile() {
|
|
5094
|
+
if (this.meta.volatile) throw new TypeError("volatile schema is already wrapped");
|
|
5095
|
+
return this.extra("volatile", true);
|
|
5096
|
+
};
|
|
4972
5097
|
const resolvers = {};
|
|
5098
|
+
const checkedVolatile = Symbol("checked-volatile-schema");
|
|
5099
|
+
function validateVolatileSchema(schema, path = [], blocked = false, seen = /* @__PURE__ */ new Map()) {
|
|
5100
|
+
const states = seen.get(schema) ?? /* @__PURE__ */ new Set();
|
|
5101
|
+
if (states.has(blocked)) return;
|
|
5102
|
+
states.add(blocked);
|
|
5103
|
+
seen.set(schema, states);
|
|
5104
|
+
if (schema.meta?.volatile && blocked) throw new ValidationError("volatile fields require a fixed object path without an enclosing volatile field", { path });
|
|
5105
|
+
const nested = blocked || !!schema.meta?.volatile;
|
|
5106
|
+
if (schema.dict) for (const [key, child] of Object.entries(schema.dict)) validateVolatileSchema(child, [...path, key], nested, seen);
|
|
5107
|
+
if (schema.sKey) validateVolatileSchema(schema.sKey, [...path, "<key>"], true, seen);
|
|
5108
|
+
if (schema.inner && (schema.type !== "lazy" || schema.inner[kSchema])) validateVolatileSchema(schema.inner, [...path, "*"], true, seen);
|
|
5109
|
+
if (schema.list) for (let index = 0; index < schema.list.length; index++) validateVolatileSchema(schema.list[index], [...path, String(index)], true, seen);
|
|
5110
|
+
}
|
|
4973
5111
|
Schema.extend = function extend(type, resolve$1) {
|
|
4974
5112
|
resolvers[type] = resolve$1;
|
|
4975
5113
|
};
|
|
4976
5114
|
Schema.resolve = function resolve$1(data, schema, options = {}, strict = false) {
|
|
4977
5115
|
if (!schema) return [data];
|
|
5116
|
+
if (!options[checkedVolatile]) {
|
|
5117
|
+
validateVolatileSchema(schema, options.path);
|
|
5118
|
+
options = {
|
|
5119
|
+
...options,
|
|
5120
|
+
[checkedVolatile]: true
|
|
5121
|
+
};
|
|
5122
|
+
}
|
|
5123
|
+
if (schema.meta?.volatile) {
|
|
5124
|
+
const inner = Schema(schema);
|
|
5125
|
+
inner.meta = {
|
|
5126
|
+
...schema.meta,
|
|
5127
|
+
volatile: false
|
|
5128
|
+
};
|
|
5129
|
+
const [value, adapted] = Schema.resolve(data, inner, options, strict);
|
|
5130
|
+
try {
|
|
5131
|
+
return [createVolatile(value), adapted];
|
|
5132
|
+
} catch (error) {
|
|
5133
|
+
throw new ValidationError(error instanceof Error ? error.message : String(error), options);
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
4978
5136
|
if (options.ignore?.(data, schema)) return [data];
|
|
4979
5137
|
if (isNullable(data) && schema.type !== "lazy") {
|
|
4980
5138
|
if (schema.meta.required) throw new ValidationError(`missing required value`, options);
|
|
@@ -5077,6 +5235,7 @@ Schema.extend("lazy", (data, schema, options, strict) => {
|
|
|
5077
5235
|
...schema.meta,
|
|
5078
5236
|
...schema.inner.meta
|
|
5079
5237
|
};
|
|
5238
|
+
validateVolatileSchema(schema.inner, options.path, true);
|
|
5080
5239
|
}
|
|
5081
5240
|
return Schema.resolve(data, schema.inner, options, strict);
|
|
5082
5241
|
});
|
|
@@ -5176,7 +5335,7 @@ function property(data, key, schema, options) {
|
|
|
5176
5335
|
} catch (e) {
|
|
5177
5336
|
if (!options?.autofix) throw e;
|
|
5178
5337
|
delete data[key];
|
|
5179
|
-
return schema.meta.default;
|
|
5338
|
+
return schema.meta.volatile ? createVolatile(schema.meta.default) : schema.meta.default;
|
|
5180
5339
|
}
|
|
5181
5340
|
}
|
|
5182
5341
|
Schema.extend("array", (data, { inner, meta }, options) => {
|
|
@@ -5341,6 +5500,7 @@ const Config = Schema.object({
|
|
|
5341
5500
|
hostLockPolicy: Schema.string(),
|
|
5342
5501
|
hostLockRuntimeRoot: Schema.string(),
|
|
5343
5502
|
hostLockProfileRoot: Schema.string(),
|
|
5503
|
+
hostLockTrust: Schema.string(),
|
|
5344
5504
|
hostLockPackages: Schema.array(Schema.object({
|
|
5345
5505
|
name: Schema.string().required(),
|
|
5346
5506
|
version: Schema.string(),
|
|
@@ -5375,9 +5535,11 @@ function resolveConfig(config) {
|
|
|
5375
5535
|
for (const key of [
|
|
5376
5536
|
"hostLockPolicy",
|
|
5377
5537
|
"hostLockRuntimeRoot",
|
|
5378
|
-
"hostLockProfileRoot"
|
|
5538
|
+
"hostLockProfileRoot",
|
|
5539
|
+
"hostLockTrust"
|
|
5379
5540
|
]) if (config[key] !== void 0 && (typeof config[key] !== "string" || !config[key])) throw new TypeError(`${key} must be a non-empty string`);
|
|
5380
5541
|
return {
|
|
5542
|
+
...typeof config.hostLockTrust === "string" ? { hostLockTrust: config.hostLockTrust } : {},
|
|
5381
5543
|
...typeof config.hostLockPolicy === "string" ? { hostLockPolicy: config.hostLockPolicy } : {},
|
|
5382
5544
|
...typeof config.hostLockRuntimeRoot === "string" ? { hostLockRuntimeRoot: config.hostLockRuntimeRoot } : {},
|
|
5383
5545
|
...typeof config.hostLockProfileRoot === "string" ? { hostLockProfileRoot: config.hostLockProfileRoot } : {},
|
|
@@ -5633,11 +5795,11 @@ function appendPrivateLedger(root, input, kind, payload) {
|
|
|
5633
5795
|
const expectedContext = contextDigest(context, root);
|
|
5634
5796
|
const anchored = readAnchors(root).get(session);
|
|
5635
5797
|
if (anchored !== void 0 && anchored !== expectedContext) return false;
|
|
5636
|
-
const snapshot = anchored === void 0 ? {
|
|
5798
|
+
const snapshot$1 = anchored === void 0 ? {
|
|
5637
5799
|
records: [],
|
|
5638
5800
|
damaged: false
|
|
5639
5801
|
} : readPrivateLedger(root, context);
|
|
5640
|
-
if (snapshot.damaged) return false;
|
|
5802
|
+
if (snapshot$1.damaged) return false;
|
|
5641
5803
|
if (anchored === void 0) {
|
|
5642
5804
|
const unsignedAnchor = {
|
|
5643
5805
|
version: 1,
|
|
@@ -5658,7 +5820,7 @@ function appendPrivateLedger(root, input, kind, payload) {
|
|
|
5658
5820
|
}
|
|
5659
5821
|
if (kind === "release_settlement") {
|
|
5660
5822
|
const settlement = normalizeSettlement(payload);
|
|
5661
|
-
const reservation = settlement && [...snapshot.records].reverse().find((record$3) => record$3.kind === "release_reservation" && record$3.payload.contractId === settlement.contractId && record$3.payload.operation === settlement.operation && record$3.payload.callId === settlement.callId);
|
|
5823
|
+
const reservation = settlement && [...snapshot$1.records].reverse().find((record$3) => record$3.kind === "release_reservation" && record$3.payload.contractId === settlement.contractId && record$3.payload.operation === settlement.operation && record$3.payload.callId === settlement.callId);
|
|
5662
5824
|
if (!reservation) return false;
|
|
5663
5825
|
payload = {
|
|
5664
5826
|
...payload,
|
|
@@ -5671,8 +5833,8 @@ function appendPrivateLedger(root, input, kind, payload) {
|
|
|
5671
5833
|
version: 1,
|
|
5672
5834
|
session_sha256: session,
|
|
5673
5835
|
context_sha256: expectedContext,
|
|
5674
|
-
position: snapshot.records.length + 1,
|
|
5675
|
-
prior_sha256: snapshot.records.at(-1)?.record_sha256 ?? null,
|
|
5836
|
+
position: snapshot$1.records.length + 1,
|
|
5837
|
+
prior_sha256: snapshot$1.records.at(-1)?.record_sha256 ?? null,
|
|
5676
5838
|
kind,
|
|
5677
5839
|
payload
|
|
5678
5840
|
};
|
|
@@ -5702,8 +5864,8 @@ function appendPrivateLedger(root, input, kind, payload) {
|
|
|
5702
5864
|
}
|
|
5703
5865
|
}
|
|
5704
5866
|
}
|
|
5705
|
-
function applyPrivateLedger(projection, snapshot) {
|
|
5706
|
-
if (snapshot.damaged || projection.releaseContracts.length > 0 && snapshot.anchored === false) {
|
|
5867
|
+
function applyPrivateLedger(projection, snapshot$1) {
|
|
5868
|
+
if (snapshot$1.damaged || projection.releaseContracts.length > 0 && snapshot$1.anchored === false) {
|
|
5707
5869
|
projection.releaseStateDamaged = true;
|
|
5708
5870
|
if (!projection.releaseDiagnostics.some((row) => row.reasonCode === "private_ledger_damaged")) projection.releaseDiagnostics.push({
|
|
5709
5871
|
seq: 0,
|
|
@@ -5712,7 +5874,7 @@ function applyPrivateLedger(projection, snapshot) {
|
|
|
5712
5874
|
return;
|
|
5713
5875
|
}
|
|
5714
5876
|
const reservations = /* @__PURE__ */ new Map();
|
|
5715
|
-
for (const record$2 of snapshot.records) if (record$2.kind === "release_reservation") {
|
|
5877
|
+
for (const record$2 of snapshot$1.records) if (record$2.kind === "release_reservation") {
|
|
5716
5878
|
const normalized = normalizeReservation(record$2.payload);
|
|
5717
5879
|
const contract = normalized && projection.releaseContracts.find((entry) => entry.contractId === normalized.contractId);
|
|
5718
5880
|
if (!normalized || !contract || record$2.payload.contract_sha256 !== privateLedgerContractDigest(contract) || typeof record$2.payload.target_sha256 !== "string") {
|
|
@@ -5756,8 +5918,8 @@ function applyPrivateLedger(projection, snapshot) {
|
|
|
5756
5918
|
else if (OUTCOME_STRENGTH[pinned.outcome] >= OUTCOME_STRENGTH[projection.releaseSettlements[index].outcome]) projection.releaseSettlements[index] = pinned;
|
|
5757
5919
|
}
|
|
5758
5920
|
}
|
|
5759
|
-
function hasPrivateRestartIntent(snapshot, resolutionCallId, serviceId, preGeneration) {
|
|
5760
|
-
return !snapshot.damaged && snapshot.records.some((record$2) => record$2.kind === "restart_intent" && record$2.payload.resolution_call_id === resolutionCallId && record$2.payload.service_id === serviceId && record$2.payload.pre_generation === preGeneration);
|
|
5921
|
+
function hasPrivateRestartIntent(snapshot$1, resolutionCallId, serviceId, preGeneration) {
|
|
5922
|
+
return !snapshot$1.damaged && snapshot$1.records.some((record$2) => record$2.kind === "restart_intent" && record$2.payload.resolution_call_id === resolutionCallId && record$2.payload.service_id === serviceId && record$2.payload.pre_generation === preGeneration);
|
|
5761
5923
|
}
|
|
5762
5924
|
|
|
5763
5925
|
//#endregion
|
|
@@ -5893,13 +6055,9 @@ function authorizeMutationFromProjection(projection, request) {
|
|
|
5893
6055
|
}
|
|
5894
6056
|
const PROTOCOL_CORRECTION_NOTICE = "Context Guard protocol correction: root-authorized work remains pending; continue with tools or obtain a typed boundary.";
|
|
5895
6057
|
/**
|
|
5896
|
-
* Establish a boundary
|
|
5897
|
-
*
|
|
5898
|
-
*
|
|
5899
|
-
* Replay reads boundaries from the `context_guard_boundary` call/result pair, so
|
|
5900
|
-
* a Guard-created boundary is written in exactly that wire shape rather than in
|
|
5901
|
-
* a private side channel — otherwise it would not survive a reload, and a
|
|
5902
|
-
* boundary that only exists in memory is not a persisted wait or stop.
|
|
6058
|
+
* Establish a Guard-owned boundary as a durable producer notice. V4 Stop hooks
|
|
6059
|
+
* run outside tool steps, so replay requalifies the notice request and verifies
|
|
6060
|
+
* its candidate digest instead of inventing a tool call/result envelope.
|
|
5903
6061
|
*
|
|
5904
6062
|
* Returns the boundary only after the durable flush succeeded. A failed flush
|
|
5905
6063
|
* reports the failure instead of a boundary, because an unflushed record must
|
|
@@ -5909,35 +6067,10 @@ async function establishBoundary(agent, runtime, flush, request) {
|
|
|
5909
6067
|
const projection = runtime.projection;
|
|
5910
6068
|
const candidate = qualifyBoundary(projection, request);
|
|
5911
6069
|
if (candidate.persistedResult !== "accepted") return { reasonCode: candidate.reasonCode };
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
step: session.seq,
|
|
5917
|
-
callId,
|
|
5918
|
-
name: "context_guard_boundary",
|
|
5919
|
-
arguments: JSON.stringify({
|
|
5920
|
-
disposition: request.disposition,
|
|
5921
|
-
qualification_kind: request.qualificationKind,
|
|
5922
|
-
qualification_ids: request.qualificationIds
|
|
5923
|
-
})
|
|
5924
|
-
});
|
|
5925
|
-
session.append("tool/result", {
|
|
5926
|
-
turn: 0,
|
|
5927
|
-
step: session.seq,
|
|
5928
|
-
message: createToolResultMessage({
|
|
5929
|
-
callId,
|
|
5930
|
-
content: [{
|
|
5931
|
-
type: "text",
|
|
5932
|
-
text: JSON.stringify({
|
|
5933
|
-
status: candidate.persistedResult,
|
|
5934
|
-
reason_code: candidate.reasonCode,
|
|
5935
|
-
boundary: { candidate_sha256: candidate.candidateSha256 }
|
|
5936
|
-
})
|
|
5937
|
-
}],
|
|
5938
|
-
isError: false
|
|
5939
|
-
})
|
|
5940
|
-
}, { surfaceOp: "append" });
|
|
6070
|
+
agent.session.append("user/message", pluginNoticeMessage(`${BOUNDARY_RECORD_PREFIX}${JSON.stringify({
|
|
6071
|
+
request,
|
|
6072
|
+
candidate_sha256: candidate.candidateSha256
|
|
6073
|
+
})}`, "recording a qualified stop boundary"), { surfaceOp: "append" });
|
|
5941
6074
|
let durable = false;
|
|
5942
6075
|
try {
|
|
5943
6076
|
durable = await flush();
|
|
@@ -5991,8 +6124,9 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
5991
6124
|
durable = false;
|
|
5992
6125
|
}
|
|
5993
6126
|
runtime.setDurability(durable);
|
|
5994
|
-
runtime.sync();
|
|
6127
|
+
runtime.sync({ revalidateHostLock: true });
|
|
5995
6128
|
if (!durable) return "boundary_flush_failed";
|
|
6129
|
+
const hostSupported = access$1.hostSupported && runtime.projection.hostStatus === "supported";
|
|
5996
6130
|
const rootInstruction = latestRootInstruction(agent.session?.snapshotEvents?.() ?? []);
|
|
5997
6131
|
if (rootInstruction !== void 0 && isRootPauseRequest(rootInstruction.text) && !runtime.projection.handledControlSeqs.has(rootInstruction.seq) && access$1.pauseAccess) {
|
|
5998
6132
|
agent.session.append("user/message", createUserMessage({
|
|
@@ -6004,7 +6138,7 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6004
6138
|
})}`
|
|
6005
6139
|
}],
|
|
6006
6140
|
source: {
|
|
6007
|
-
kind: "
|
|
6141
|
+
kind: "context-guard",
|
|
6008
6142
|
plugin: "context-guard",
|
|
6009
6143
|
form: "notice",
|
|
6010
6144
|
summary: boundContextSummary("carrying the root pause request to the host")
|
|
@@ -6029,7 +6163,7 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6029
6163
|
text: record$2
|
|
6030
6164
|
}],
|
|
6031
6165
|
source: {
|
|
6032
|
-
kind: "
|
|
6166
|
+
kind: "context-guard",
|
|
6033
6167
|
plugin: "context-guard",
|
|
6034
6168
|
form: "notice",
|
|
6035
6169
|
summary: boundContextSummary("recording a turn boundary without relevant progress")
|
|
@@ -6052,7 +6186,7 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6052
6186
|
text: PROTOCOL_CORRECTION_NOTICE
|
|
6053
6187
|
}],
|
|
6054
6188
|
source: {
|
|
6055
|
-
kind: "
|
|
6189
|
+
kind: "context-guard",
|
|
6056
6190
|
plugin: "context-guard",
|
|
6057
6191
|
form: "notice",
|
|
6058
6192
|
summary: boundContextSummary("requesting the one allowed protocol correction step")
|
|
@@ -6061,7 +6195,7 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6061
6195
|
return decision.reason ?? "protocol_correction_steer";
|
|
6062
6196
|
}
|
|
6063
6197
|
if (decision.reason === "no_progress_bounded_disarm") {
|
|
6064
|
-
if (!access$1.goalAccess || !
|
|
6198
|
+
if (!access$1.goalAccess || !hostSupported) {
|
|
6065
6199
|
runtime.projection.integrity = "unknown";
|
|
6066
6200
|
runtime.projection.integrityViolations.push("boundary_host_lock_unsupported");
|
|
6067
6201
|
return "boundary_host_lock_unsupported";
|
|
@@ -6079,7 +6213,7 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6079
6213
|
const current = runtime.projection.boundaries.at(-1);
|
|
6080
6214
|
const alreadyCurrent = current && isCurrentAcceptedBoundary(runtime.projection, current) && current.disposition === "user_wait" && current.qualificationIds.slice().sort().join(",") === waiting.join(",");
|
|
6081
6215
|
if (waiting.length > 0 && !alreadyCurrent) {
|
|
6082
|
-
if (!
|
|
6216
|
+
if (!hostSupported) {
|
|
6083
6217
|
runtime.projection.integrity = "unknown";
|
|
6084
6218
|
runtime.projection.integrityViolations.push("boundary_host_lock_unsupported");
|
|
6085
6219
|
return "boundary_host_lock_unsupported";
|
|
@@ -6096,15 +6230,17 @@ async function handleGuardTurnStopping(agent, runtime, access$1) {
|
|
|
6096
6230
|
if (decision.reason !== "accepted_boundary_pending_effectuation") return decision.reason ?? "safe_yield_pending_preserved";
|
|
6097
6231
|
const boundary = runtime.projection.boundaries.at(-1);
|
|
6098
6232
|
if (!boundary || !isCurrentAcceptedBoundary(runtime.projection, boundary)) return "boundary_candidate_stale";
|
|
6099
|
-
if (boundary.goalRef && (!access$1.goalAccess || !
|
|
6233
|
+
if (boundary.goalRef && (!access$1.goalAccess || !hostSupported)) {
|
|
6100
6234
|
runtime.projection.integrity = "unknown";
|
|
6101
6235
|
runtime.projection.integrityViolations.push("boundary_host_lock_unsupported");
|
|
6102
6236
|
return "boundary_host_lock_unsupported";
|
|
6103
6237
|
}
|
|
6104
|
-
const requalify = boundary.disposition === "external_wait" ? async () =>
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6238
|
+
const requalify = boundary.disposition === "external_wait" ? async () => {
|
|
6239
|
+
return (access$1.refreshExternalWaitCapability?.() ?? access$1.externalWaitCapability)?.status === "supported" && boundary.qualificationIds.every((id) => {
|
|
6240
|
+
const row = access$1.readExternalOperation(id);
|
|
6241
|
+
return row?.status === "running" || row?.status === "pending";
|
|
6242
|
+
});
|
|
6243
|
+
} : void 0;
|
|
6108
6244
|
const effect = await effectuateBoundary(boundary, {
|
|
6109
6245
|
...access$1.goalAccess ?? {
|
|
6110
6246
|
get: async () => void 0,
|
|
@@ -6169,7 +6305,6 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
|
|
|
6169
6305
|
const persistenceCorrectionAttempts = projection.persistenceCorrectionAttempts;
|
|
6170
6306
|
const rebuild = () => {
|
|
6171
6307
|
const previousReleaseContracts = projection.releaseContracts.length;
|
|
6172
|
-
if (refreshHostLock) hostLock = refreshHostLock();
|
|
6173
6308
|
const header = session.header;
|
|
6174
6309
|
const priorRecoveryDigest = projection.lastRecoveryDigest;
|
|
6175
6310
|
const sessionHeader = sessionHeaderForDigest(session);
|
|
@@ -6256,11 +6391,33 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
|
|
|
6256
6391
|
observedCompactionSeq = derived.lastCompactionSeq;
|
|
6257
6392
|
}
|
|
6258
6393
|
};
|
|
6259
|
-
const
|
|
6394
|
+
const entryStorage = new AsyncLocalStorage();
|
|
6395
|
+
const sync = (options) => {
|
|
6396
|
+
if (options?.revalidateHostLock && refreshHostLock) {
|
|
6397
|
+
const cell = entryStorage.getStore();
|
|
6398
|
+
if (cell && !cell.stale) hostLock = cell.lock;
|
|
6399
|
+
else {
|
|
6400
|
+
hostLock = refreshHostLock();
|
|
6401
|
+
if (cell) {
|
|
6402
|
+
cell.lock = hostLock;
|
|
6403
|
+
cell.stale = false;
|
|
6404
|
+
queueMicrotask(() => {
|
|
6405
|
+
cell.stale = true;
|
|
6406
|
+
});
|
|
6407
|
+
}
|
|
6408
|
+
}
|
|
6409
|
+
}
|
|
6260
6410
|
rebuild();
|
|
6261
6411
|
};
|
|
6412
|
+
const runHostLockEntry = async (operation) => {
|
|
6413
|
+
if (!refreshHostLock) return await operation();
|
|
6414
|
+
return await entryStorage.run({
|
|
6415
|
+
lock: void 0,
|
|
6416
|
+
stale: true
|
|
6417
|
+
}, async () => await operation());
|
|
6418
|
+
};
|
|
6262
6419
|
const setEnabled = (_enabled) => {
|
|
6263
|
-
|
|
6420
|
+
sync({ revalidateHostLock: true });
|
|
6264
6421
|
};
|
|
6265
6422
|
const setDurability = (confirmed) => {
|
|
6266
6423
|
durabilityConfirmed = confirmed;
|
|
@@ -6297,6 +6454,7 @@ function createRuntime(agent, config, hostLock = DEFAULT_HOST_LOCK, readGoalStat
|
|
|
6297
6454
|
return [...pendingRecoveryCauses];
|
|
6298
6455
|
},
|
|
6299
6456
|
sync,
|
|
6457
|
+
runHostLockEntry,
|
|
6300
6458
|
setEnabled,
|
|
6301
6459
|
setDurability,
|
|
6302
6460
|
markRecoveryNeeded,
|
|
@@ -6318,18 +6476,21 @@ function isDelegatedSession(session) {
|
|
|
6318
6476
|
return header?.origin === "subagent" || typeof header?.delegationDepth === "number" && header.delegationDepth > 0 || typeof header?.parentSession === "string";
|
|
6319
6477
|
}
|
|
6320
6478
|
/** Never reinterpret a legacy injected snapshot as freshly accepted core/v1. */
|
|
6321
|
-
function revalidateCoreLock(config, expected) {
|
|
6479
|
+
function revalidateCoreLock(config, expected, providedSession) {
|
|
6322
6480
|
if (config.hostLockPolicy !== "dsh-core/v1" || !config.hostLockRuntimeRoot || !config.hostLockProfileRoot) return {
|
|
6323
6481
|
...expected,
|
|
6324
6482
|
status: "unavailable",
|
|
6325
6483
|
goalAvailable: false,
|
|
6326
6484
|
reasonCode: "host_lock_migration_required"
|
|
6327
6485
|
};
|
|
6486
|
+
const session = providedSession ?? createHostAuditSession();
|
|
6328
6487
|
try {
|
|
6329
|
-
const
|
|
6488
|
+
const runtimeRoot = session.realpath(config.hostLockRuntimeRoot);
|
|
6489
|
+
const profileRoot = session.realpath(config.hostLockProfileRoot);
|
|
6490
|
+
const actual = evaluateActiveHostLock(runtimeRoot, profileRoot, {
|
|
6330
6491
|
platform: config.hostLockPlatform,
|
|
6331
6492
|
profileKind: config.hostLockProfile
|
|
6332
|
-
});
|
|
6493
|
+
}, session, config.hostLockTrust);
|
|
6333
6494
|
if (actual.status !== "supported") return actual;
|
|
6334
6495
|
if (actual.digest !== expected.digest) return {
|
|
6335
6496
|
...actual,
|
|
@@ -6337,7 +6498,7 @@ function revalidateCoreLock(config, expected) {
|
|
|
6337
6498
|
goalAvailable: false,
|
|
6338
6499
|
reasonCode: "host_lock_installed_graph_drift"
|
|
6339
6500
|
};
|
|
6340
|
-
const audited = auditedForegroundRenderers(
|
|
6501
|
+
const audited = auditedForegroundRenderers(runtimeRoot, profileRoot, session);
|
|
6341
6502
|
return audited.length ? {
|
|
6342
6503
|
...actual,
|
|
6343
6504
|
auditedForegroundRenderers: audited,
|
|
@@ -6354,17 +6515,18 @@ function revalidateCoreLock(config, expected) {
|
|
|
6354
6515
|
}
|
|
6355
6516
|
/** Observe one actual Host dispatch through Cordis without joining its gate. */
|
|
6356
6517
|
function registerPassiveHostWorkdirObserver(agent, hostLockAtCall, attestedRouteAtCall, sourcedRootAtCall) {
|
|
6357
|
-
if (typeof agent.ctx.on !== "function") return;
|
|
6518
|
+
if (typeof agent.ctx.on !== "function") return () => {};
|
|
6358
6519
|
const pending = /* @__PURE__ */ new WeakMap();
|
|
6359
|
-
agent.ctx.on("tools/pre-execute", async (exec, next) => {
|
|
6520
|
+
const pre = agent.ctx.on("tools/pre-execute", async (exec, next) => {
|
|
6360
6521
|
if (exec.agent === agent && (exec.name === "bash" || exec.name === "pwsh")) try {
|
|
6361
6522
|
const policy = agent.ctx.get("sandboxPolicy");
|
|
6362
|
-
const
|
|
6523
|
+
const audit = createHostAuditSession();
|
|
6524
|
+
const receipt = captureHostWorkdir(agent.session, exec, hostLockAtCall(audit), policy, await attestedRouteAtCall(exec.name, agent.ctx.get("shell"), policy, audit), sourcedRootAtCall?.(exec) ?? null, SESSION_FORMAT_VERSION);
|
|
6363
6525
|
if (receipt) pending.set(exec, receipt);
|
|
6364
6526
|
} catch {}
|
|
6365
6527
|
return next();
|
|
6366
6528
|
});
|
|
6367
|
-
agent.ctx.on("tools/post-execute", async (exec, _result, next) => {
|
|
6529
|
+
const post = agent.ctx.on("tools/post-execute", async (exec, _result, next) => {
|
|
6368
6530
|
const decision = await next();
|
|
6369
6531
|
const receipt = pending.get(exec);
|
|
6370
6532
|
pending.delete(exec);
|
|
@@ -6375,7 +6537,7 @@ function registerPassiveHostWorkdirObserver(agent, hostLockAtCall, attestedRoute
|
|
|
6375
6537
|
text: `${HOST_WORKDIR_PREFIX}${JSON.stringify(receipt)}`
|
|
6376
6538
|
}],
|
|
6377
6539
|
source: {
|
|
6378
|
-
kind: "
|
|
6540
|
+
kind: "context-guard",
|
|
6379
6541
|
plugin: "context-guard",
|
|
6380
6542
|
form: "notice",
|
|
6381
6543
|
summary: "read-only Host workdir observation"
|
|
@@ -6386,231 +6548,309 @@ function registerPassiveHostWorkdirObserver(agent, hostLockAtCall, attestedRoute
|
|
|
6386
6548
|
additionalContexts: [...decision.additionalContexts ?? [], context]
|
|
6387
6549
|
};
|
|
6388
6550
|
});
|
|
6551
|
+
return () => {
|
|
6552
|
+
pre();
|
|
6553
|
+
post();
|
|
6554
|
+
};
|
|
6389
6555
|
}
|
|
6390
6556
|
function apply(ctx, rawConfig = {}, seams = {}) {
|
|
6391
6557
|
const config = resolveConfig(rawConfig);
|
|
6392
|
-
const installedHostLock = seams.hostLock ??
|
|
6558
|
+
const installedHostLock = seams.hostLock ?? evaluateConfiguredHostLock(config.hostLockPackages ?? [], {
|
|
6393
6559
|
platform: config.hostLockPlatform,
|
|
6394
6560
|
profileKind: config.hostLockProfile
|
|
6395
|
-
});
|
|
6561
|
+
}, config.hostLockTrust, config.hostLockProfileRoot);
|
|
6396
6562
|
const runtimes = /* @__PURE__ */ new Map();
|
|
6397
6563
|
const privateLedgerRoot = seams.privateLedgerRoot ?? resolvePrivateLedgerRoot(void 0, process.env.DSH_HOME, homedir());
|
|
6398
6564
|
const hostLocks = /* @__PURE__ */ new Map();
|
|
6565
|
+
const qualifiedGoalService = (agent) => (hostLocks.get(agent) ?? installedHostLock).goalQualificationFailure ? void 0 : optionalGoalService(ctx, agent);
|
|
6399
6566
|
const ledgerContext = (agent, fallback = installedHostLock) => ({
|
|
6400
6567
|
sessionId: String(agent.session.id),
|
|
6401
6568
|
sessionHeader: structuredClone(agent.session.header),
|
|
6402
6569
|
cwd: sessionCwd(agent.session) ?? "",
|
|
6403
6570
|
hostLockDigest: (hostLocks.get(agent) ?? fallback).digest
|
|
6404
6571
|
});
|
|
6405
|
-
const
|
|
6572
|
+
const registrations = /* @__PURE__ */ new Map();
|
|
6573
|
+
const detach = (agent) => {
|
|
6574
|
+
const disposers = registrations.get(agent);
|
|
6575
|
+
registrations.delete(agent);
|
|
6576
|
+
for (const dispose of disposers?.slice().reverse() ?? []) dispose();
|
|
6577
|
+
runtimes.delete(agent);
|
|
6578
|
+
hostLocks.delete(agent);
|
|
6579
|
+
};
|
|
6580
|
+
ctx.effect?.(() => () => {
|
|
6581
|
+
for (const agent of registrations.keys()) detach(agent);
|
|
6582
|
+
});
|
|
6583
|
+
ctx.on("agent/disposed", ({ agent }) => {
|
|
6584
|
+
detach(agent);
|
|
6585
|
+
});
|
|
6586
|
+
/** One full host-lock validation for the named agent, recorded as the
|
|
6587
|
+
* agent's current authority. Every fresh-validation entry funnels here. */
|
|
6588
|
+
const fullHostLockValidation = () => {
|
|
6589
|
+
const evaluated = revalidateCoreLock(config, installedHostLock);
|
|
6590
|
+
seams.onHostLockValidation?.();
|
|
6591
|
+
return evaluated;
|
|
6592
|
+
};
|
|
6593
|
+
const refreshAgentHostLock = (agent) => {
|
|
6594
|
+
const current = bindLiveGoalCapability(seams.hostLock ?? fullHostLockValidation(), Boolean(qualifiedGoalService(agent)) && hasPinnedUpdateGoalTool(agent));
|
|
6595
|
+
hostLocks.set(agent, current);
|
|
6596
|
+
return current;
|
|
6597
|
+
};
|
|
6406
6598
|
const ensure = (agent) => {
|
|
6407
6599
|
let runtime = runtimes.get(agent);
|
|
6408
6600
|
if (!runtime) {
|
|
6409
|
-
const goals =
|
|
6410
|
-
const
|
|
6411
|
-
|
|
6412
|
-
hostLocks.set(agent, current);
|
|
6413
|
-
return current;
|
|
6414
|
-
};
|
|
6415
|
-
const agentHostLock = refreshHostLock();
|
|
6416
|
-
runtime = createRuntime(agent, config, agentHostLock, goals ? () => goals.get(agent) : void 0, refreshHostLock, privateLedgerRoot ? () => readPrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0, privateLedgerRoot ? () => initializePrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0);
|
|
6601
|
+
const goals = qualifiedGoalService(agent);
|
|
6602
|
+
const agentHostLock = refreshAgentHostLock(agent);
|
|
6603
|
+
runtime = createRuntime(agent, config, agentHostLock, goals ? () => goals.get(agent) : void 0, () => refreshAgentHostLock(agent), privateLedgerRoot ? () => readPrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0, privateLedgerRoot ? () => initializePrivateLedger(privateLedgerRoot, ledgerContext(agent, agentHostLock)) : void 0);
|
|
6417
6604
|
runtimes.set(agent, runtime);
|
|
6418
|
-
hostLocks.set(agent, agentHostLock);
|
|
6419
6605
|
}
|
|
6420
6606
|
return runtime;
|
|
6421
6607
|
};
|
|
6422
6608
|
ctx.commands.register(createContextGuardCommand((agent) => ensure(agent).projection, (agent, enabled) => ensure(agent).setEnabled(enabled), (agent) => ensure(agent).sync(), (agent) => ensure(agent).lifecycle));
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6609
|
+
const attach = (agent, source) => {
|
|
6610
|
+
if (registrations.has(agent)) {
|
|
6611
|
+
if (source === "resume" || source === "compact") {
|
|
6612
|
+
const runtime = ensure(agent);
|
|
6613
|
+
runtime.sync();
|
|
6614
|
+
runtime.projection.lastRecoveryDigest = void 0;
|
|
6615
|
+
runtime.markRecoveryNeeded(source === "resume" ? "resume" : "compaction");
|
|
6616
|
+
}
|
|
6617
|
+
return;
|
|
6429
6618
|
}
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
return sourcedNamedTestRoot(runtime.projection, agent.session, exec.arguments);
|
|
6435
|
-
});
|
|
6436
|
-
agent.ctx.tools.register(createRebindTool(() => runtime.projection, async () => {
|
|
6437
|
-
const durable = await ctx.sessions.flush(agent.session);
|
|
6438
|
-
runtime.setDurability(durable);
|
|
6439
|
-
runtime.sync();
|
|
6440
|
-
return durable;
|
|
6441
|
-
}));
|
|
6442
|
-
agent.ctx.tools.register(createCheckpointTool(() => runtime.projection, () => runtime.markRecoveryNeeded("checkpoint_followup"), async () => {
|
|
6443
|
-
const durable = await ctx.sessions.flush(agent.session);
|
|
6444
|
-
runtime.setDurability(durable);
|
|
6445
|
-
runtime.sync();
|
|
6446
|
-
return durable;
|
|
6447
|
-
}));
|
|
6448
|
-
agent.ctx.tools.register(createBoundaryTool(() => runtime.projection, async () => {
|
|
6449
|
-
const durable = await ctx.sessions.flush(agent.session);
|
|
6450
|
-
runtime.setDurability(durable);
|
|
6451
|
-
runtime.sync();
|
|
6452
|
-
return durable;
|
|
6453
|
-
}, () => runtime.markRecoveryNeeded("boundary_update")));
|
|
6454
|
-
/** Persist release state outside provider-visible Session history. */
|
|
6455
|
-
const persistReleaseRecord = async (toolAgent, kind, payload) => {
|
|
6456
|
-
if (toolAgent.session !== agent.session) return false;
|
|
6457
|
-
if (!sessionCwd(agent.session)) return false;
|
|
6458
|
-
const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), kind, payload);
|
|
6459
|
-
runtime.sync();
|
|
6460
|
-
return durable;
|
|
6619
|
+
const disposers = [];
|
|
6620
|
+
registrations.set(agent, disposers);
|
|
6621
|
+
const own = (dispose) => {
|
|
6622
|
+
if (dispose) disposers.push(dispose);
|
|
6461
6623
|
};
|
|
6462
|
-
const
|
|
6463
|
-
|
|
6464
|
-
...
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6624
|
+
const ownedTools = {
|
|
6625
|
+
register: (...args) => own(agent.ctx.tools.register(...args)),
|
|
6626
|
+
guard: (...args) => own(agent.ctx.tools.guard(...args))
|
|
6627
|
+
};
|
|
6628
|
+
try {
|
|
6629
|
+
const runtime = ensure(agent);
|
|
6630
|
+
runtime.sync();
|
|
6631
|
+
if (source === "resume" || source === "compact") {
|
|
6632
|
+
runtime.projection.lastRecoveryDigest = void 0;
|
|
6633
|
+
runtime.markRecoveryNeeded(source === "resume" ? "resume" : "compaction");
|
|
6634
|
+
}
|
|
6635
|
+
own(registerPassiveHostWorkdirObserver(agent, (audit) => {
|
|
6636
|
+
if (seams.hostLock) return seams.hostLock;
|
|
6637
|
+
const evaluated = revalidateCoreLock(config, installedHostLock, audit);
|
|
6638
|
+
seams.onHostLockValidation?.();
|
|
6639
|
+
return evaluated;
|
|
6640
|
+
}, (tool, provider, policy, audit) => config.hostLockRuntimeRoot && config.hostLockProfileRoot ? auditedDefaultWorkdirProvider(config.hostLockRuntimeRoot, config.hostLockProfileRoot, tool, provider, policy, audit) : false, (exec) => {
|
|
6641
|
+
runtime.sync();
|
|
6642
|
+
return sourcedNamedTestRoot(runtime.projection, agent.session, exec.arguments);
|
|
6643
|
+
}));
|
|
6644
|
+
ownedTools.register(createRebindTool(() => runtime.projection, async () => {
|
|
6469
6645
|
const durable = await ctx.sessions.flush(agent.session);
|
|
6470
6646
|
runtime.setDurability(durable);
|
|
6471
6647
|
runtime.sync();
|
|
6472
6648
|
return durable;
|
|
6473
|
-
}
|
|
6474
|
-
|
|
6475
|
-
runtime.sync();
|
|
6476
|
-
return authorizeMutationFromProjection(runtime.projection, request);
|
|
6477
|
-
},
|
|
6478
|
-
marketOrigin: optionalMarketOrigin(ctx, agent),
|
|
6479
|
-
hasRestartIntent: (resolutionCallId, serviceId, preGeneration) => hasPrivateRestartIntent(readPrivateLedger(privateLedgerRoot, ledgerContext(agent)), resolutionCallId, serviceId, preGeneration),
|
|
6480
|
-
releaseGate: async (request) => {
|
|
6481
|
-
runtime.sync();
|
|
6482
|
-
const projection = runtime.projection;
|
|
6483
|
-
if (!(projection.policy === "release" || projection.releaseContracts.length > 0)) return {
|
|
6484
|
-
status: "denied",
|
|
6485
|
-
reasonCode: "release_contract_not_adopted"
|
|
6486
|
-
};
|
|
6487
|
-
const observed = { ...request.observed };
|
|
6488
|
-
const declaredRef = releaseContractFor(projection, request.operation)?.candidate.ref;
|
|
6489
|
-
if (declaredRef !== void 0 && observed.ref === void 0) {
|
|
6490
|
-
const refSha = await resolveAuditedRef(sessionCwd(runtime.session), declaredRef, evidenceOptions, requestSignal());
|
|
6491
|
-
if (refSha !== void 0) {
|
|
6492
|
-
observed.ref = declaredRef;
|
|
6493
|
-
observed.refSha = refSha;
|
|
6494
|
-
}
|
|
6495
|
-
}
|
|
6496
|
-
const decision = releasePreEffectDecision(projection, {
|
|
6497
|
-
operation: request.operation,
|
|
6498
|
-
observed,
|
|
6499
|
-
resolvedTarget: request.resolvedTarget,
|
|
6500
|
-
nowEpochMs: Date.now()
|
|
6501
|
-
});
|
|
6502
|
-
if (decision.status !== "granted" || decision.contractId === void 0) return {
|
|
6503
|
-
status: "denied",
|
|
6504
|
-
reasonCode: decision.reasonCode
|
|
6505
|
-
};
|
|
6506
|
-
const grantedContract = projection.releaseContracts.find((entry) => entry.contractId === decision.contractId);
|
|
6507
|
-
if (!grantedContract) return {
|
|
6508
|
-
status: "denied",
|
|
6509
|
-
reasonCode: "release_state_damaged"
|
|
6510
|
-
};
|
|
6511
|
-
return await persistReleaseRecord(agent, "release_reservation", {
|
|
6512
|
-
contractId: decision.contractId,
|
|
6513
|
-
operation: request.operation,
|
|
6514
|
-
callId: request.callId,
|
|
6515
|
-
startedAtSeq: 0,
|
|
6516
|
-
status: "in_flight",
|
|
6517
|
-
contract_sha256: privateLedgerContractDigest(grantedContract),
|
|
6518
|
-
target_sha256: privateLedgerTargetDigest(request.resolvedTarget),
|
|
6519
|
-
...observed.artifactSri !== void 0 ? { observedArtifactSri: observed.artifactSri } : {}
|
|
6520
|
-
}) ? {
|
|
6521
|
-
status: "granted",
|
|
6522
|
-
reasonCode: decision.reasonCode,
|
|
6523
|
-
contractId: decision.contractId
|
|
6524
|
-
} : {
|
|
6525
|
-
status: "denied",
|
|
6526
|
-
reasonCode: "release_reservation_not_durable"
|
|
6527
|
-
};
|
|
6528
|
-
},
|
|
6529
|
-
releaseSettle: async (request) => {
|
|
6530
|
-
const contractId = request.contractId ?? releaseContractFor(runtime.projection, request.operation)?.contractId ?? "unknown";
|
|
6531
|
-
const contract = runtime.projection.releaseContracts.find((entry) => entry.contractId === contractId);
|
|
6532
|
-
const reservation = reservationFor(runtime.projection, contractId, request.callId);
|
|
6533
|
-
let outcome = request.effect === "not_effected" ? "not_effected" : "unknown";
|
|
6534
|
-
if (request.effect === "completed" && contract) outcome = readbackSettlesContract(contract, request.readback, reservation?.observedArtifactSri) === "settled" ? "settled" : "unknown";
|
|
6535
|
-
await persistReleaseRecord(agent, "release_settlement", {
|
|
6536
|
-
contractId,
|
|
6537
|
-
operation: request.operation,
|
|
6538
|
-
callId: request.callId,
|
|
6539
|
-
settledAtSeq: 0,
|
|
6540
|
-
readback: request.readback,
|
|
6541
|
-
outcome,
|
|
6542
|
-
settlement_source: "effect"
|
|
6543
|
-
});
|
|
6544
|
-
},
|
|
6545
|
-
persistRestartIntent: async (toolAgent, intent) => {
|
|
6546
|
-
if (toolAgent.session !== agent.session) return false;
|
|
6547
|
-
if (!sessionCwd(agent.session)) return false;
|
|
6548
|
-
const snapshot = readPrivateLedger(privateLedgerRoot, ledgerContext(agent));
|
|
6549
|
-
if (snapshot.damaged || !snapshot.anchored) return false;
|
|
6550
|
-
const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), "restart_intent", {
|
|
6551
|
-
resolution_call_id: intent.resolutionCallId,
|
|
6552
|
-
service_id: intent.serviceId,
|
|
6553
|
-
pre_generation: intent.preGeneration
|
|
6554
|
-
});
|
|
6555
|
-
runtime.sync();
|
|
6556
|
-
return durable;
|
|
6557
|
-
}
|
|
6558
|
-
};
|
|
6559
|
-
agent.ctx.tools.register(createEvidenceTool(evidenceOptions));
|
|
6560
|
-
agent.ctx.tools.register(createNativeFileObserver({
|
|
6561
|
-
fs: ctx.fs,
|
|
6562
|
-
flush: (session) => ctx.sessions.flush(session)
|
|
6563
|
-
}));
|
|
6564
|
-
agent.ctx.tools.register(createNativeGitObserver({ flush: (session) => ctx.sessions.flush(session) }));
|
|
6565
|
-
agent.ctx.tools.register(createTestReadinessObserver({
|
|
6566
|
-
getProjection: () => runtime.projection,
|
|
6567
|
-
fs: ctx.fs,
|
|
6568
|
-
flush: (session) => ctx.sessions.flush(session)
|
|
6569
|
-
}));
|
|
6570
|
-
agent.ctx.tools.register(createActionTool(evidenceOptions));
|
|
6571
|
-
agent.ctx.tools.register(createPrepareTool({
|
|
6572
|
-
getProjection: () => runtime.projection,
|
|
6573
|
-
hostCapability: (action) => {
|
|
6574
|
-
const evaluation = createHostCapabilityEvaluator(hostLocks.get(agent) ?? installedHostLock)(action);
|
|
6575
|
-
return {
|
|
6576
|
-
status: evaluation.status,
|
|
6577
|
-
reasonCode: evaluation.reasonCode
|
|
6578
|
-
};
|
|
6579
|
-
},
|
|
6580
|
-
commandTemplate: (action) => GIT_COMMAND_TEMPLATES[action],
|
|
6581
|
-
refreshProjection: async () => {
|
|
6649
|
+
}));
|
|
6650
|
+
ownedTools.register(createCheckpointTool(() => runtime.projection, () => runtime.markRecoveryNeeded("checkpoint_followup"), async () => {
|
|
6582
6651
|
const durable = await ctx.sessions.flush(agent.session);
|
|
6583
6652
|
runtime.setDurability(durable);
|
|
6584
6653
|
runtime.sync();
|
|
6585
6654
|
return durable;
|
|
6586
|
-
}
|
|
6587
|
-
|
|
6588
|
-
agent.ctx.tools.register(createInterpretTool({
|
|
6589
|
-
getProjection: () => runtime.projection,
|
|
6590
|
-
refreshProjection: async () => {
|
|
6655
|
+
}, () => runtime.sync({ revalidateHostLock: true })));
|
|
6656
|
+
ownedTools.register(createBoundaryTool(() => runtime.projection, async () => {
|
|
6591
6657
|
const durable = await ctx.sessions.flush(agent.session);
|
|
6592
6658
|
runtime.setDurability(durable);
|
|
6593
6659
|
runtime.sync();
|
|
6594
6660
|
return durable;
|
|
6595
|
-
}
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6661
|
+
}, () => runtime.markRecoveryNeeded("boundary_update")));
|
|
6662
|
+
/** Persist release state outside provider-visible Session history. */
|
|
6663
|
+
const persistReleaseRecord = async (toolAgent, kind, payload) => {
|
|
6664
|
+
if (toolAgent.session !== agent.session) return false;
|
|
6665
|
+
if (!sessionCwd(agent.session)) return false;
|
|
6666
|
+
const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), kind, payload);
|
|
6667
|
+
runtime.sync();
|
|
6668
|
+
return durable;
|
|
6669
|
+
};
|
|
6670
|
+
const hostCapabilityFromCache = (action) => createHostCapabilityEvaluator(hostLocks.get(agent) ?? installedHostLock)(action);
|
|
6671
|
+
const evidenceOptions = {
|
|
6672
|
+
hostCapability: hostCapabilityFromCache,
|
|
6673
|
+
...seams.commandRunner ? { commandRunner: seams.commandRunner } : {},
|
|
6674
|
+
...seams.fetcher ? { fetcher: seams.fetcher } : {},
|
|
6675
|
+
...seams.readExecutableIdentity ? { readExecutableIdentity: seams.readExecutableIdentity } : {},
|
|
6676
|
+
...seams.allowLoopbackHttpRegistry ? { allowLoopbackHttpRegistry: true } : {},
|
|
6677
|
+
preEffectVeto: () => {
|
|
6678
|
+
runtime.sync({ revalidateHostLock: true });
|
|
6679
|
+
return runtime.projection.hostStatus === "supported";
|
|
6680
|
+
},
|
|
6681
|
+
prepareMutation: async (toolAgent) => {
|
|
6682
|
+
if (toolAgent.session !== agent.session) return false;
|
|
6683
|
+
const durable = await ctx.sessions.flush(agent.session);
|
|
6684
|
+
runtime.setDurability(durable);
|
|
6685
|
+
runtime.sync();
|
|
6686
|
+
return durable;
|
|
6687
|
+
},
|
|
6688
|
+
authorizeMutation: (request) => {
|
|
6689
|
+
runtime.sync({ revalidateHostLock: true });
|
|
6690
|
+
return authorizeMutationFromProjection(runtime.projection, request);
|
|
6691
|
+
},
|
|
6692
|
+
marketOrigin: optionalMarketOrigin(ctx, agent),
|
|
6693
|
+
hasRestartIntent: (resolutionCallId, serviceId, preGeneration) => hasPrivateRestartIntent(readPrivateLedger(privateLedgerRoot, ledgerContext(agent)), resolutionCallId, serviceId, preGeneration),
|
|
6694
|
+
releaseGate: async (request) => {
|
|
6695
|
+
const observed = { ...request.observed };
|
|
6696
|
+
const declaredRef = releaseContractFor(runtime.projection, request.operation)?.candidate.ref;
|
|
6697
|
+
if (declaredRef !== void 0 && observed.ref === void 0) {
|
|
6698
|
+
const refSha = await resolveAuditedRef(sessionCwd(runtime.session), declaredRef, evidenceOptions, requestSignal());
|
|
6699
|
+
if (refSha !== void 0) {
|
|
6700
|
+
observed.ref = declaredRef;
|
|
6701
|
+
observed.refSha = refSha;
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
runtime.sync({ revalidateHostLock: true });
|
|
6705
|
+
const projection = runtime.projection;
|
|
6706
|
+
if (!(projection.policy === "release" || projection.releaseContracts.length > 0)) return {
|
|
6707
|
+
status: "denied",
|
|
6708
|
+
reasonCode: "release_contract_not_adopted"
|
|
6709
|
+
};
|
|
6710
|
+
if (projection.hostStatus !== "supported") return {
|
|
6711
|
+
status: "denied",
|
|
6712
|
+
reasonCode: projection.hostReasonCode ?? "host_lock_unavailable"
|
|
6713
|
+
};
|
|
6714
|
+
const decision = releasePreEffectDecision(projection, {
|
|
6715
|
+
operation: request.operation,
|
|
6716
|
+
observed,
|
|
6717
|
+
resolvedTarget: request.resolvedTarget,
|
|
6718
|
+
nowEpochMs: Date.now()
|
|
6719
|
+
});
|
|
6720
|
+
if (decision.status !== "granted" || decision.contractId === void 0) return {
|
|
6721
|
+
status: "denied",
|
|
6722
|
+
reasonCode: decision.reasonCode
|
|
6723
|
+
};
|
|
6724
|
+
const grantedContract = projection.releaseContracts.find((entry) => entry.contractId === decision.contractId);
|
|
6725
|
+
if (!grantedContract) return {
|
|
6726
|
+
status: "denied",
|
|
6727
|
+
reasonCode: "release_state_damaged"
|
|
6728
|
+
};
|
|
6729
|
+
return await persistReleaseRecord(agent, "release_reservation", {
|
|
6730
|
+
contractId: decision.contractId,
|
|
6731
|
+
operation: request.operation,
|
|
6732
|
+
callId: request.callId,
|
|
6733
|
+
startedAtSeq: 0,
|
|
6734
|
+
status: "in_flight",
|
|
6735
|
+
contract_sha256: privateLedgerContractDigest(grantedContract),
|
|
6736
|
+
target_sha256: privateLedgerTargetDigest(request.resolvedTarget),
|
|
6737
|
+
...observed.artifactSri !== void 0 ? { observedArtifactSri: observed.artifactSri } : {}
|
|
6738
|
+
}) ? {
|
|
6739
|
+
status: "granted",
|
|
6740
|
+
reasonCode: decision.reasonCode,
|
|
6741
|
+
contractId: decision.contractId
|
|
6742
|
+
} : {
|
|
6743
|
+
status: "denied",
|
|
6744
|
+
reasonCode: "release_reservation_not_durable"
|
|
6745
|
+
};
|
|
6746
|
+
},
|
|
6747
|
+
releaseSettle: async (request) => {
|
|
6748
|
+
const contractId = request.contractId ?? releaseContractFor(runtime.projection, request.operation)?.contractId ?? "unknown";
|
|
6749
|
+
const contract = runtime.projection.releaseContracts.find((entry) => entry.contractId === contractId);
|
|
6750
|
+
const reservation = reservationFor(runtime.projection, contractId, request.callId);
|
|
6751
|
+
let outcome = request.effect === "not_effected" ? "not_effected" : "unknown";
|
|
6752
|
+
if (request.effect === "completed" && contract) outcome = readbackSettlesContract(contract, request.readback, reservation?.observedArtifactSri) === "settled" ? "settled" : "unknown";
|
|
6753
|
+
await persistReleaseRecord(agent, "release_settlement", {
|
|
6754
|
+
contractId,
|
|
6755
|
+
operation: request.operation,
|
|
6756
|
+
callId: request.callId,
|
|
6757
|
+
settledAtSeq: 0,
|
|
6758
|
+
readback: request.readback,
|
|
6759
|
+
outcome,
|
|
6760
|
+
settlement_source: "effect"
|
|
6761
|
+
});
|
|
6762
|
+
},
|
|
6763
|
+
persistRestartIntent: async (toolAgent, intent) => {
|
|
6764
|
+
if (toolAgent.session !== agent.session) return false;
|
|
6765
|
+
if (!sessionCwd(agent.session)) return false;
|
|
6766
|
+
const snapshot$1 = readPrivateLedger(privateLedgerRoot, ledgerContext(agent));
|
|
6767
|
+
if (snapshot$1.damaged || !snapshot$1.anchored) return false;
|
|
6768
|
+
const durable = appendPrivateLedger(privateLedgerRoot, ledgerContext(agent), "restart_intent", {
|
|
6769
|
+
resolution_call_id: intent.resolutionCallId,
|
|
6770
|
+
service_id: intent.serviceId,
|
|
6771
|
+
pre_generation: intent.preGeneration
|
|
6772
|
+
});
|
|
6773
|
+
runtime.sync();
|
|
6774
|
+
return durable;
|
|
6775
|
+
}
|
|
6776
|
+
};
|
|
6777
|
+
ownedTools.register(createEvidenceTool(evidenceOptions));
|
|
6778
|
+
ownedTools.register(createNativeFileObserver({
|
|
6779
|
+
fs: ctx.fs,
|
|
6780
|
+
flush: (session) => ctx.sessions.flush(session)
|
|
6781
|
+
}));
|
|
6782
|
+
ownedTools.register(createNativeGitObserver({ flush: (session) => ctx.sessions.flush(session) }));
|
|
6783
|
+
ownedTools.register(createTestReadinessObserver({
|
|
6784
|
+
getProjection: () => runtime.projection,
|
|
6785
|
+
fs: ctx.fs,
|
|
6786
|
+
flush: (session) => ctx.sessions.flush(session)
|
|
6787
|
+
}));
|
|
6788
|
+
const actionTool = createActionTool({
|
|
6789
|
+
...evidenceOptions,
|
|
6790
|
+
hostCapability: (action) => {
|
|
6791
|
+
runtime.sync({ revalidateHostLock: true });
|
|
6792
|
+
return createHostCapabilityEvaluator(hostLocks.get(agent) ?? installedHostLock)(action);
|
|
6793
|
+
}
|
|
6794
|
+
});
|
|
6795
|
+
ownedTools.register({
|
|
6796
|
+
...actionTool,
|
|
6797
|
+
execute: (...args) => runtime.runHostLockEntry(() => actionTool.execute(...args))
|
|
6798
|
+
});
|
|
6799
|
+
ownedTools.register(createPrepareTool({
|
|
6800
|
+
getProjection: () => runtime.projection,
|
|
6801
|
+
hostCapability: (action) => {
|
|
6802
|
+
const evaluation = createHostCapabilityEvaluator(hostLocks.get(agent) ?? installedHostLock)(action);
|
|
6803
|
+
return {
|
|
6804
|
+
status: evaluation.status,
|
|
6805
|
+
reasonCode: evaluation.reasonCode
|
|
6806
|
+
};
|
|
6807
|
+
},
|
|
6808
|
+
commandTemplate: (action) => GIT_COMMAND_TEMPLATES[action],
|
|
6809
|
+
refreshProjection: async () => {
|
|
6810
|
+
const durable = await ctx.sessions.flush(agent.session);
|
|
6811
|
+
runtime.setDurability(durable);
|
|
6812
|
+
runtime.sync();
|
|
6813
|
+
return durable;
|
|
6814
|
+
}
|
|
6815
|
+
}));
|
|
6816
|
+
ownedTools.register(createInterpretTool({
|
|
6817
|
+
getProjection: () => runtime.projection,
|
|
6818
|
+
refreshProjection: async () => {
|
|
6819
|
+
const durable = await ctx.sessions.flush(agent.session);
|
|
6820
|
+
runtime.setDurability(durable);
|
|
6821
|
+
runtime.sync();
|
|
6822
|
+
return durable;
|
|
6823
|
+
}
|
|
6824
|
+
}));
|
|
6825
|
+
ownedTools.register(createReleaseTool({
|
|
6826
|
+
getProjection: () => runtime.projection,
|
|
6827
|
+
fetcher: evidenceOptions.fetcher,
|
|
6828
|
+
...evidenceOptions.allowLoopbackHttpRegistry ? { allowLoopbackHttpRegistry: true } : {},
|
|
6829
|
+
persistSettlement: async (request) => persistReleaseRecord(request.agent, "release_settlement", {
|
|
6830
|
+
contractId: request.contractId,
|
|
6831
|
+
operation: request.operation,
|
|
6832
|
+
callId: request.callId,
|
|
6833
|
+
settledAtSeq: 0,
|
|
6834
|
+
readback: request.readback,
|
|
6835
|
+
outcome: request.outcome,
|
|
6836
|
+
settlement_source: "reconcile"
|
|
6837
|
+
})
|
|
6838
|
+
}));
|
|
6839
|
+
ownedTools.register(createExternalOperationTool((id, toolAgent) => readExternalOperation(ctx, toolAgent, id), () => evaluateExternalWaitCapability(hostLocks.get(agent) ?? installedHostLock)));
|
|
6840
|
+
ownedTools.guard((exec) => {
|
|
6841
|
+
if (exec.name === "update_goal" && exec.arguments?.action === "complete" && runtime.projection.enabled) runtime.sync({ revalidateHostLock: true });
|
|
6842
|
+
return goalCompletionDenial(runtime.projection, exec.name, exec.arguments);
|
|
6843
|
+
});
|
|
6844
|
+
} catch (error) {
|
|
6845
|
+
detach(agent);
|
|
6846
|
+
throw error;
|
|
6847
|
+
}
|
|
6848
|
+
};
|
|
6849
|
+
ctx.on("agent/created", ({ agent, source, signal }) => {
|
|
6850
|
+
signal?.throwIfAborted();
|
|
6851
|
+
return attach(agent, source);
|
|
6613
6852
|
});
|
|
6853
|
+
for (const agent of ctx.get?.("agents")?.list() ?? []) attach(agent);
|
|
6614
6854
|
ctx.on("agent/pre-step", async ({ agent }, next) => {
|
|
6615
6855
|
const durability = await ctx.sessions.flush(agent.session);
|
|
6616
6856
|
const runtime = ensure(agent);
|
|
@@ -6657,7 +6897,7 @@ function apply(ctx, rawConfig = {}, seams = {}) {
|
|
|
6657
6897
|
text: `${title}\n${recovery}`
|
|
6658
6898
|
}],
|
|
6659
6899
|
source: {
|
|
6660
|
-
kind: "
|
|
6900
|
+
kind: "context-guard",
|
|
6661
6901
|
plugin: "context-guard",
|
|
6662
6902
|
form: "notice",
|
|
6663
6903
|
summary: boundContextSummary("recovering open task requirements")
|
|
@@ -6670,11 +6910,12 @@ function apply(ctx, rawConfig = {}, seams = {}) {
|
|
|
6670
6910
|
});
|
|
6671
6911
|
ctx.on("agent/turn-stopping", async ({ agent }) => {
|
|
6672
6912
|
const runtime = ensure(agent);
|
|
6673
|
-
const goals =
|
|
6913
|
+
const goals = qualifiedGoalService(agent);
|
|
6674
6914
|
await handleGuardTurnStopping(agent, runtime, {
|
|
6675
6915
|
flush: () => ctx.sessions.flush(agent.session),
|
|
6676
6916
|
hostSupported: runtime.projection.hostStatus === "supported",
|
|
6677
6917
|
externalWaitCapability: evaluateExternalWaitCapability(hostLocks.get(agent) ?? installedHostLock),
|
|
6918
|
+
refreshExternalWaitCapability: () => evaluateExternalWaitCapability(hostLocks.get(agent) ?? installedHostLock),
|
|
6678
6919
|
...goals ? { goalAccess: {
|
|
6679
6920
|
get: async () => normalizeGoalState(await goals.get(agent)),
|
|
6680
6921
|
disarm: async () => normalizeGoalState(await goals.disarm(agent))
|
|
@@ -6685,15 +6926,15 @@ function apply(ctx, rawConfig = {}, seams = {}) {
|
|
|
6685
6926
|
}
|
|
6686
6927
|
function readExternalOperation(ctx, agent, id) {
|
|
6687
6928
|
if (!agent || !id) return void 0;
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6929
|
+
if (!agent.session || agent.id !== agent.session.id) return void 0;
|
|
6930
|
+
try {
|
|
6931
|
+
const service = agent.ctx.get("jobs") ?? ctx.get("jobs");
|
|
6932
|
+
if (!service) return void 0;
|
|
6933
|
+
const row = service.get(JobId(id), agent.id);
|
|
6934
|
+
if (!row || row.id !== id) return void 0;
|
|
6694
6935
|
return {
|
|
6695
6936
|
id,
|
|
6696
|
-
status:
|
|
6937
|
+
status: row.status === "running" ? "running" : row.status === "stopping" ? "pending" : row.status === "completed" ? "completed" : row.status === "killed" || row.status === "failed" ? "failed" : "unknown",
|
|
6697
6938
|
adapterId: "dsh.jobs.v1"
|
|
6698
6939
|
};
|
|
6699
6940
|
} catch {
|
|
@@ -6715,7 +6956,7 @@ function pluginNoticeMessage(text, summaryLabel) {
|
|
|
6715
6956
|
text
|
|
6716
6957
|
}],
|
|
6717
6958
|
source: {
|
|
6718
|
-
kind: "
|
|
6959
|
+
kind: "context-guard",
|
|
6719
6960
|
plugin: "context-guard",
|
|
6720
6961
|
form: "notice",
|
|
6721
6962
|
summary: boundContextSummary(summaryLabel)
|
|
@@ -6811,7 +7052,7 @@ async function replayRawV2(input) {
|
|
|
6811
7052
|
text: PROTOCOL_V6_NOTICE
|
|
6812
7053
|
}],
|
|
6813
7054
|
source: {
|
|
6814
|
-
kind: "
|
|
7055
|
+
kind: "context-guard",
|
|
6815
7056
|
plugin: "context-guard",
|
|
6816
7057
|
form: "notice",
|
|
6817
7058
|
summary: "v6 replay boundary"
|
|
@@ -6855,7 +7096,7 @@ async function replayRawV2(input) {
|
|
|
6855
7096
|
const runtime = createRuntime(agent, { activation: "always" }, lock, () => void 0);
|
|
6856
7097
|
runtime.setDurability(true);
|
|
6857
7098
|
runtime.sync();
|
|
6858
|
-
const snapshot = sessionCoreSnapshot(session.snapshotEvents(), runtime.projection);
|
|
7099
|
+
const snapshot$1 = sessionCoreSnapshot(session.snapshotEvents(), runtime.projection);
|
|
6859
7100
|
const stopCore = runtime.projection.coreV2 ?? null;
|
|
6860
7101
|
const stop = await handleGuardTurnStopping(agent, runtime, {
|
|
6861
7102
|
flush: async () => true,
|
|
@@ -6870,7 +7111,7 @@ async function replayRawV2(input) {
|
|
|
6870
7111
|
const projection = runtime.projection;
|
|
6871
7112
|
const postSnapshot = sessionCoreSnapshot(session.snapshotEvents(), projection);
|
|
6872
7113
|
return {
|
|
6873
|
-
stop_core_snapshot: snapshot ?? null,
|
|
7114
|
+
stop_core_snapshot: snapshot$1 ?? null,
|
|
6874
7115
|
stop_core_projection: stopCore,
|
|
6875
7116
|
stop,
|
|
6876
7117
|
post_turn_core_snapshot: postSnapshot ?? null,
|
|
@@ -6900,4 +7141,4 @@ async function replayRawV2(input) {
|
|
|
6900
7141
|
}
|
|
6901
7142
|
|
|
6902
7143
|
//#endregion
|
|
6903
|
-
export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION,
|
|
7144
|
+
export { ACTION_MANIFEST, ACTION_MANIFEST_VERSION, ACTIVE_HOST_COHORT_ID, ACTIVE_HOST_COHORT_IDS, ACTIVE_HOST_LAUNCHER_VERSION, BASE_HOST_PACKAGES, BOUNDARY_RECORD_PREFIX, 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, HOST_VALIDATED_VERSIONS, HostProfileError, HostTrustError, LATEST_TESTED_HOST_VERSION, LEGACY_QUALIFICATION, MIN_RECOVERY_CHAR_BUDGET, MIN_SUPPORTED_HOST_VERSION, NO_PROGRESS_RECORD_PREFIX, NO_PROGRESS_TURNS_BEFORE_STOP, PROOF_CAPABILITY_MATRIX, PROOF_KINDS, PROOF_KINDS_V2, PROOF_MANIFEST_DOMAIN_V2, PROOF_PROTOCOL_VERSION, PROOF_PROTOCOL_VERSION_V2, PROTOCOL_V3_NOTICE, PROTOCOL_V4_NOTICE, PROTOCOL_V5_NOTICE, PROTOCOL_V6_NOTICE, RC020_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, V6_ORDINARY_COMPLETION_RULE, V6_ORDINARY_COMPLETION_RULE_COMPACT, V6_ORDINARY_COMPLETION_RULE_SHORT, acquireHostTrust, actionCompatible, actionHasCertificationPath, actionVerbMatches, activeRendererModule, admissibleForRemoval, apply, applyUpgradeEligibility, assessmentAction, assessmentOutcomePredicate, auditedDefaultWorkdirHost, auditedDefaultWorkdirProvider, auditedForegroundRenderers, auditedHostImplementation, authorityCaptureCounts, availableBoundaryQualifications, bindExecutableIdentity, bindLiveGoalCapability, bindProofToProjection, bindProofV2ToProjection, bindingIndividuallyAccepted, bindingSatisfies, boundedArtifactChoiceMatches, canonicalArgvFromCommand, canonicalProjection, canonicalizePath, capabilityConsequence, capabilityFactOf, capabilityRemedyPhrase, captureClause, captureItem, carriesCleanupCondition, certifyCheckpoint, claimedBatchHasRealRootInput, clarifiedSpanOf, classifyClause, classifyCompletionClaim, classifyTaskIntent, classifyUserInteraction, clauseAsksOwnQuestion, clauseIsGoverned, clauseIsProtected, cleanupConditionFor, closingHint, combineHostPolicy, commitIndexSnapshotDigest, commitTreeSnapshotDigest, compareHostVersions, confirmRebind, createGitPrestateEnvelope, createProjection, createProofManifest, createProofManifestV2, currentActionBases, currentContractDigest, decideTurnBoundary, decideTurnStopping, decisionBoundaryKey, deriveItemDiagnosis, deriveProjection, digestStrings, effectuateBoundary, environmentDefaultRepositoryTarget, evaluateActiveHostLock, evaluateConfiguredHostLock, evaluateExternalWaitCapability, evaluateGraphDerivedHostLock, evaluateHostCapability, evaluateHostLock, evaluateMinimumHostVersion, evaluateToolSurfaceCapability, evidenceAvailabilityReason, evidenceCoverage, evidenceFromPersistedToolResult, evidenceMatchesItem, executeRevalidatedGitEffect, explanationHasActionResidue, extractArtifactPaths, extractMethod, extractOperation, extractTextContent, extractToolSubject, firstStepGuidance, firstStepGuidanceV6, gitCommandMatchesTarget, goalCompletionDenial, governedClauseRestrictsExecution, hasCurrentCertificate, hasOrderedCoordination, hasQuestionScope, hasWorkPredicate, hostLockContextFromComposedDump, hostLockRowsFromComposedDump, hostTrustDigest, 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, nativeFileTwoRole, normalizeClause, observeAssistantOutcome, openItems, opensConditionLead, opensWithDirective, packageRowsFromActiveGraph, packageRowsFromPnpmLock, parseConfirmationMessage, parseGitCommandManifest, parseHostTrust, parseHostVersion, parsePwshCommand, parseShellCommand, partialFailureOf, persistedToolResultStatus, prepareActiveHostTrust, prepareTargetHostTrust, presentExplanationHead, previewFirstStepInjection, progressFingerprint, projectCoreV2, projectSessionCoreV2, proofCapabilityReport, proofDigest, proofDigestV2, proofEvidenceConstraints, proofHostSurfacesOf, proofOperationMatches, proofV2Rejection, proposeRebind, proposeRebindOutcome, proposeRebindV042, qualificationOfClause, qualifyBoundary, qualifyHostTrust, questionHeadsClause, readActiveHostGraph, rebindAttemptKey, rebindResponse, recoveryDigest, recoveryTitle, registryArchiveFiles, registryArchiveModules, relevantEvidence, removalIsComplete, removalIsPartiallyKnown, renderRecoveryPacket, replayRawV2, replayRebindResult, reportingHeadGoverns, requestedIdentityKey, requestedTargetAuthorizesMutation, requestedTargetMatchesResolved, requiredSubjectsOf, resolveActiveProfileHostLock, resolveInstalledHostLock, restatedContentOf, revalidateGitPrestate, rootLocatorFlavor, sanitizeClauseText, sanitizeUrl, satisfiesSupportedHostRange, scopeCoverageDigest, segmentAuthorityBlocks, segmentClauses, selectHostCohort, semanticActionFromCommand, semanticActionFromText, semanticActionOfScope, sessionQuery, sessionQueryV2, sha256, snapshotSessionEvents, splitTextFragments, statefulActionsOfScope, supersedeItem, testOutcomePredicate, v6CurrentRootBoundaries, v6TestPredicate, validateActionManifest, validateActionTarget, validateManifest, validateProofManifest, validateProofManifestV2, verbIsNegated, verifiedLinearCommitReadback, verifyComposedHostLockDump, withDurability };
|