@sema-agent/core
Version:
Stateless, task-oriented AI agent core
120 lines (119 loc) • 11.4 kB
JavaScript
import { persistedReadDenyEntryProblem } from "../../tools/fs/read-deny.js";
import { isAskOrigin } from "../ask-origin.js";
import { CHECKPOINT_FEATURES, CheckpointError, checkpointVersionOf, MAX_SUPPORTED_CHECKPOINT_VERSION, realApprovalOrgFact } from "../checkpoint-store.js";
import { constraintChainDigest, constraintChainEntryOfSuppliedLayer } from "../tool-policy.js";
import { readFrozenSkillGrants } from "../skill-grant.js";
export function resumeCheckpointScreen(input) {
const { cp, resumeSignal, internals, runner } = input;
const { realApproval: realApprovalRow, face: faceRow, f012: f012Row } = CHECKPOINT_FEATURES;
if (checkpointVersionOf(cp) > MAX_SUPPORTED_CHECKPOINT_VERSION) {
throw new CheckpointError("checkpoint.unsupported_version", `checkpoint version ${checkpointVersionOf(cp)} is newer than this worker supports (max ${MAX_SUPPORTED_CHECKPOINT_VERSION})`, { reason: "version_newer" });
}
const preCasGateBit = cp.gate.kind === "irreversible_ask" ? cp.gate.realApproval : undefined;
const preCasBitWellFormed = preCasGateBit !== undefined && typeof preCasGateBit === "object" && isAskOrigin(preCasGateBit.origin);
const faceSaysGoverned = (cp.state.readFace?.realApproval) === true;
const preCasBitViolation = checkpointVersionOf(cp) === realApprovalRow.version
? !preCasBitWellFormed
: checkpointVersionOf(cp) < realApprovalRow.version
? preCasGateBit !== undefined
: faceSaysGoverned
? !preCasBitWellFormed
: preCasGateBit !== undefined && !preCasBitWellFormed;
if (preCasBitViolation) {
throw new CheckpointError("checkpoint.invalid_outcome", checkpointVersionOf(cp) >= realApprovalRow.version
? `a v${checkpointVersionOf(cp)} checkpoint's realApproval gate bit must be well-formed (origin a member of the closed ask-origin set)${checkpointVersionOf(cp) === realApprovalRow.version ? " and present on an irreversible_ask gate" : ""} — this row's is not; refusing to resume a damaged real-approval row (corruption / downgrade guard), the checkpoint stays pending`
: `a v${checkpointVersionOf(cp)} checkpoint carries a realApproval gate bit no release of that version ever minted — refusing to honor a fabricated origin (corruption / forgery guard), the checkpoint stays pending`, { reason: checkpointVersionOf(cp) >= realApprovalRow.version ? "real_approval_damaged" : "real_approval_forged" });
}
{
const faceSectionRaw = cp.state.readFace;
const faceCandidate = faceSectionRaw !== undefined && typeof faceSectionRaw === "object" && faceSectionRaw !== null
? faceSectionRaw
: undefined;
const faceWellFormed = faceCandidate !== undefined &&
(faceCandidate.face === "open" || faceCandidate.face === "roots") &&
(faceCandidate.realApproval === undefined || faceCandidate.realApproval === true) &&
(faceCandidate.denyEntries === undefined ||
(Array.isArray(faceCandidate.denyEntries) &&
faceCandidate.denyEntries.every((e) => persistedReadDenyEntryProblem(e) === null)));
if (checkpointVersionOf(cp) >= faceRow.version ? !faceWellFormed : faceSectionRaw !== undefined) {
throw new CheckpointError("checkpoint.invalid_outcome", checkpointVersionOf(cp) >= faceRow.version
? `a v${checkpointVersionOf(cp)} checkpoint must carry a well-formed read-face section (state.readFace) — this row's is missing or malformed; refusing to resume a damaged read-face row (corruption / downgrade guard), the checkpoint stays pending`
: `a v${checkpointVersionOf(cp)} checkpoint carries a read-face section no release of that version ever minted — refusing to honor a fabricated read-face state (corruption / forgery guard), the checkpoint stays pending`, { reason: checkpointVersionOf(cp) >= faceRow.version ? "read_face_damaged" : "read_face_forged" });
}
const writeFaceSectionRaw = cp.state.writeFace;
if (writeFaceSectionRaw !== undefined) {
const c = typeof writeFaceSectionRaw === "object" && writeFaceSectionRaw !== null ? writeFaceSectionRaw : undefined;
if (c === undefined || !(c.face === "open" || c.face === "roots")) {
throw new CheckpointError("checkpoint.invalid_outcome", `this checkpoint carries a write-face section (state.writeFace) that is not well-formed — refusing to resume a damaged write-face row (corruption guard), the checkpoint stays pending`, { reason: "write_face_damaged" });
}
}
if (readFrozenSkillGrants(cp.state.skillGrants) === undefined)
throw new CheckpointError("checkpoint.invalid_outcome", "this checkpoint carries a skill-grant section (state.skillGrants) that does not read as grant rows — refusing to resume without the grant rows and refusals it carries (corruption guard), the checkpoint stays pending", { reason: "skill_grants_damaged" });
}
if (realApprovalOrgFact(preCasGateBit) !== undefined && runner.deps.permissionRuleStore?.partitions.org !== true) {
throw new CheckpointError("checkpoint.unsupported_version", `this checkpoint's approval was minted under organization governance (org ${String(realApprovalOrgFact(preCasGateBit))}, routed as ${String(preCasGateBit?.origin)}) and this worker has no org adjudication wiring (its permission-rule store carries no org partition) — a governed approval may only be redeemed where governance can be enforced; the checkpoint stays pending, resume it on an org-wired worker`, { reason: "governed_unwired" });
}
const retiredWalltimeTotal = cp.resourceLedger?.totalWalltimeSec;
if (retiredWalltimeTotal !== undefined) {
throw new CheckpointError("checkpoint.walltime_axis_retired", "this checkpoint's ledger carries a cross-slice WALL-CLOCK allocation (resourceLedger.totalWalltimeSec), an axis this engine version retired — " +
"resuming here would run the leg with that ceiling unenforced. Rejected pre-CAS (the checkpoint stays pending): finish it on a worker of the " +
"previous release, or start a fresh task bounded by resourceSuspend.totalTokens / totalBudgetUsd.");
}
if (resumeSignal?.aborted === true && cp.status === "pending") {
throw new CheckpointError("checkpoint.resume_aborted", "the resume was handed an ALREADY-ABORTED signal — refusing to consume the approval on a leg that cannot run it (the checkpoint stays pending and is resumable with a live signal)");
}
if (cp.state.workspaceHandle !== undefined && runner.deps.executionEnvFactory === undefined) {
throw new CheckpointError("checkpoint.unsupported_version", "checkpoint has a remote workspaceHandle but no RunnerDeps.executionEnvFactory is wired to rebuild the env", { reason: "env_factory_missing" });
}
if (cp.state.workspaceHandle !== undefined && internals?.requestedCwd !== undefined) {
throw new CheckpointError("checkpoint.cwd_conflicts_restore", `internals.requestedCwd ("${internals.requestedCwd}") cannot be combined with a checkpoint workspace restore — ` +
"the restored workspace's own mount path is authoritative for the task root. Drop requestedCwd on resume legs " +
"(the checkpoint stays pending and is resumable without it).");
}
if (cp.state.inheritedGate?.requiresParentConstraint === true) {
const supplied = internals?.inheritedGate?.parentConstraints?.length ?? 0;
if (supplied === 0) {
throw new CheckpointError("resume.parent_constraint_missing", "this checkpoint's task ran under inherited parent-policy constraints (state.inheritedGate.requiresParentConstraint) " +
"— the live policy/onAsk closures cannot be persisted, so the resume must re-supply them via " +
"resumeStream(token, outcome, taskConfig, internals) with internals.inheritedGate.parentConstraints; " +
"rejected pre-CAS (the checkpoint stays pending) rather than silently dropping the ancestors' gate");
}
const expected = cp.state.inheritedGate.parentConstraintCount;
if (expected !== undefined && supplied !== expected) {
throw new CheckpointError("resume.parent_constraint_mismatch", `re-supplied ${supplied} parent constraint(s) but the checkpoint recorded ${expected} — a partial/mismatched ` +
"re-supply would run the resumed leg under a different ancestor chain than it suspended with; " +
"rejected pre-CAS (the checkpoint stays pending) — re-resume with the full original chain");
}
if (checkpointVersionOf(cp) >= f012Row.version &&
(cp.state.inheritedGate.constraintChain === undefined || cp.state.inheritedGate.constraintDigest === undefined)) {
throw new CheckpointError("checkpoint.invalid_outcome", `a v${checkpointVersionOf(cp)} checkpoint that requires parent constraints must carry BOTH the frozen constraintChain and its constraintDigest (they are minted in one write with the version stamp) — this row carries neither or only one; refusing to fall back to the count-only contract on a damaged row (corruption / downgrade guard), the checkpoint stays pending`, { reason: "constraint_chain_missing" });
}
const expectedDigest = cp.state.inheritedGate.constraintDigest;
if (expectedDigest !== undefined) {
const persistedChain = cp.state.inheritedGate.constraintChain;
if (persistedChain === undefined || constraintChainDigest(persistedChain) !== expectedDigest) {
throw new CheckpointError("resume.parent_constraint_mismatch", "the checkpoint's OWN recorded constraint chain does not match its recorded digest " +
"(corrupt / inconsistently-minted row) — the frozen deny data the resume would execute is not the data the " +
"digest authenticates; rejected pre-CAS (the checkpoint stays pending)");
}
const suppliedDigest = constraintChainDigest((internals?.inheritedGate?.parentConstraints ?? []).map((pc, i) => constraintChainEntryOfSuppliedLayer(pc, persistedChain[i])));
if (suppliedDigest !== expectedDigest) {
throw new CheckpointError("resume.parent_constraint_mismatch", "the re-supplied parent-constraint chain's projection content does not match what the checkpoint recorded " +
`(recorded ${expectedDigest}, re-supplied ${suppliedDigest}) — a same-shape chain with different frozen ` +
"deny data would run the resumed leg under a different ancestor gate than it suspended with; " +
"rejected pre-CAS (the checkpoint stays pending) — re-resume with the original chain's policies " +
"(including, when the row recorded one, the ancestor's auto-mode arming recipe verbatim)");
}
}
}
const resumeInternals = internals?.inheritedGate?.parentConstraints !== undefined
? {
...internals,
inheritedGate: {
...internals.inheritedGate,
parentConstraints: Object.freeze(internals.inheritedGate.parentConstraints.map((e) => ({ ...e }))),
},
}
: internals;
return { resumeInternals };
}