@sabaiway/agent-workflow-kit 13.0.0 → 13.1.0

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.
@@ -131,13 +131,21 @@ const short = (v) => {
131
131
  // ── the closed vocabulary ─────────────────────────────────────────────────────────────────────────
132
132
 
133
133
  export const DELEGATION_SCHEMA_VERSION = 1;
134
+ export const BASELINE_KINDS = deepFreeze(['head', 'checkpoint']);
135
+ export const HEAD_BASELINE = deepFreeze({ kind: 'head', treeOid: null });
136
+ export const OPTIONAL_FIELDS = deepFreeze({ dispatch: ['baseline'] });
137
+ const TREE_OID_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
138
+ export const isTreeOid = (v) => typeof v === 'string' && TREE_OID_RE.test(v);
139
+ export const readsBaseline = (dispatch) => Object.hasOwn(dispatch, 'baseline')
140
+ ? { kind: dispatch.baseline.kind, treeOid: dispatch.baseline.treeOid }
141
+ : { ...HEAD_BASELINE };
134
142
 
135
143
  export const DELEGATION_KINDS = deepFreeze(['pre-registration', 'dispatch', 'return', 'fold', 'observation', 'degrade']);
136
144
 
137
145
  // The closed key set per kind (schema + kind are implicit on every record).
138
146
  export const DELEGATION_KEY_SETS = deepFreeze({
139
147
  'pre-registration': ['waveId', 'stepClasses', 'pairingKey', 'minPerClass', 'meanLThreshold', 'firstPassNum', 'firstPassDen', 'timestamp'],
140
- dispatch: ['waveId', 'nonce', 'stepClass', 'vehicle', 'backend', 'contractDigest', 'preTreeDigest', 'baselineClean', 'deadlineS', 'retryOf', 'retryIndex', 'retryCap', 'rationale', 'timestamp'],
148
+ dispatch: ['waveId', 'nonce', 'stepClass', 'vehicle', 'backend', 'contractDigest', 'preTreeDigest', 'baselineClean', 'deadlineS', 'retryOf', 'retryIndex', 'retryCap', 'rationale', 'timestamp', 'baseline'],
141
149
  return: ['role', 'backend', 'nonce', 'contractDigest', 'preTreeDigest', 'postTreeDigest', 'diffDigest', 'diffLength', 'reportDigest', 'reportLength', 'bundleDigest', 'bundleLength', 'metric', 'outcome', 'exitStatus', 'sessionId', 'wrapperVersion', 'posture', 'timestamp'],
142
150
  fold: ['nonce', 'returnDigest', 'treeDigestAtFold', 'verdict', 'timestamp'],
143
151
  observation: ['waveId', 'stepClass', 'scope', 'metric', 'planId', 'phase', 'timestamp'],
@@ -217,6 +225,7 @@ const namesAnObject = (kind) => kind !== 'gate-output';
217
225
  // ── nested closed forms ───────────────────────────────────────────────────────────────────────────
218
226
 
219
227
  const VEHICLE_KEYS = ['requested', 'selected'];
228
+ const BASELINE_KEYS = ['kind', 'treeOid'];
220
229
  const POSTURE_KEYS = ['model', 'effort', 'tier'];
221
230
  const METRIC_KEYS = ['numeratorBytes', 'denominatorBytes', 'components', 'provenance', 'eligible', 'ineligibleReason'];
222
231
  const COMPONENT_KEYS = ['kind', 'path', 'objectId', 'bytes'];
@@ -235,6 +244,18 @@ const checkClosedKeys = (at, value, keys) => {
235
244
  return { ok: true };
236
245
  };
237
246
 
247
+ const validateBaseline = (at, baseline) => {
248
+ const closed = checkClosedKeys(at, baseline, BASELINE_KEYS);
249
+ if (!closed.ok) return closed;
250
+ if (!BASELINE_KINDS.includes(baseline.kind)) return refuse(`${at}: unknown kind ${short(baseline.kind)} — expected ${BASELINE_KINDS.join(' | ')}`);
251
+ if (baseline.treeOid !== null && (typeof baseline.treeOid !== 'string' || !TREE_OID_RE.test(baseline.treeOid))) {
252
+ return refuse(`${at}: treeOid must be null or exactly 40 or 64 lowercase hex characters (got ${short(baseline.treeOid)})`);
253
+ }
254
+ if (baseline.kind === 'head' && baseline.treeOid !== null) return refuse(`${at}: head requires treeOid null`);
255
+ if (baseline.kind === 'checkpoint' && baseline.treeOid === null) return refuse(`${at}: checkpoint requires treeOid to be non-null`);
256
+ return { ok: true };
257
+ };
258
+
238
259
  const validateVehicle = (at, vehicle) => {
239
260
  const closed = checkClosedKeys(at, vehicle, VEHICLE_KEYS);
240
261
  if (!closed.ok) return closed;
@@ -324,6 +345,7 @@ const FIELD_CHECKS = {
324
345
  firstPassNum: { ok: isByteCount, want: 'a non-negative integer first-pass numerator' },
325
346
  firstPassDen: { ok: (v) => Number.isSafeInteger(v) && v >= 1, want: 'a positive integer first-pass denominator' },
326
347
  vehicle: { ok: isPlainObject, want: 'the closed vehicle pair {requested, selected}' },
348
+ baseline: { ok: isPlainObject, want: 'the closed baseline pair {kind, treeOid}' },
327
349
  // The safe token grammar, not merely non-empty: the backend NAMES an artifact beside the store
328
350
  // (the exec receipt and its report), so a name outside this grammar records a dispatch whose own
329
351
  // receipt could never be written. One grammar on both sides, or the ledger accepts what the
@@ -375,6 +397,7 @@ const checkFields = (kind, record) => {
375
397
  return refuse(`${kind}: unknown field "${stray}" — the key set is closed (the canonical digest is identity; a stray key would fork it)`);
376
398
  }
377
399
  for (const field of fields) {
400
+ if (!Object.hasOwn(record, field) && (OPTIONAL_FIELDS[kind] ?? []).includes(field)) continue;
378
401
  if (!own.includes(field)) {
379
402
  return refuse(`${kind}: missing field "${field}" — every field of the closed set is pinned as an OWN ENUMERABLE key (the digest domain)`);
380
403
  }
@@ -492,6 +515,10 @@ export const validateDelegationRecord = (record) => {
492
515
  }
493
516
  if (record.kind === 'dispatch') {
494
517
  const vehicle = validateVehicle('dispatch: vehicle', record.vehicle);
518
+ if (Object.hasOwn(record, 'baseline')) {
519
+ const baseline = validateBaseline('dispatch: baseline', record.baseline);
520
+ if (!baseline.ok) return baseline;
521
+ }
495
522
  return vehicle.ok ? validateDispatchCrossFields(record) : vehicle;
496
523
  }
497
524
  if (record.kind === 'return') return validateReturnCrossFields(record);
@@ -3,7 +3,7 @@ import { spawnSync } from 'node:child_process';
3
3
 
4
4
  import {
5
5
  validateDelegationRecord, canonicalDelegationDigest, allowedSuccessorKinds,
6
- isThreadTerminalRecord,
6
+ isThreadTerminalRecord, readsBaseline,
7
7
  } from './dispatch-record.mjs';
8
8
  import { readRegularFileNoFollow } from './fs-read-nofollow.mjs';
9
9
  import { GIT_MAX_BUFFER } from './git-env.mjs';
@@ -175,6 +175,11 @@ export const delegationSemanticPreflight = ({ records, snapshot, storePath }) =>
175
175
  if (snapshot.stepClass !== prior.dispatch.stepClass) {
176
176
  throw stop(`refusing a retry: it declares step class "${snapshot.stepClass}" but its retry origin "${snapshot.retryOf}" was dispatched as "${prior.dispatch.stepClass}" — the pairing key is the step class, so a chain that changes it mid-way would split one attempt's accounting across two classes; nothing was written`);
177
177
  }
178
+ const base = readsBaseline(snapshot);
179
+ const priorBase = readsBaseline(prior.dispatch);
180
+ if (base.kind !== priorBase.kind || base.treeOid !== priorBase.treeOid) {
181
+ throw stop(`refusing a retry: its base {kind "${base.kind}", treeOid ${base.treeOid}} differs from its retry origin "${snapshot.retryOf}"'s {kind "${priorBase.kind}", treeOid ${priorBase.treeOid}} — a retry chain is measured against ONE base; nothing was written`);
182
+ }
178
183
  const origin = findRetryChainOrigin(records, prior.dispatch);
179
184
  if (snapshot.retryIndex > origin.retryCap) {
180
185
  throw stop(`refusing a retry: retryIndex ${snapshot.retryIndex} exceeds the retryCap ${origin.retryCap} recorded on the thread's ORIGIN dispatch ("${origin.nonce}") — a fresh contract never manufactures a fresh retry budget; nothing was written`);
@@ -2,7 +2,8 @@
2
2
  // The read half lives in dispatch-store-read.mjs so read-only consumers never reach this writer.
3
3
 
4
4
  import { computeTreeFingerprint } from './core-evidence.mjs';
5
- import { validateDelegationRecord } from './dispatch-record.mjs';
5
+ import { validateDelegationRecord, HEAD_BASELINE } from './dispatch-record.mjs';
6
+ import { computeBaseFingerprint } from './dispatch-baseline.mjs';
6
7
  import {
7
8
  delegationStoreStop,
8
9
  resolveDelegationStorePath,
@@ -30,8 +31,8 @@ export const resolveDelegationLockPath = (storePath) => `${storePath}${DELEGATIO
30
31
 
31
32
  export const UNCOMMITTED_STATE_FINGERPRINT = 'the uncommitted-state fingerprint';
32
33
 
33
- export const uncommittedStateFingerprint = (cwd = process.cwd(), fsx) => {
34
- const fingerprint = computeTreeFingerprint(cwd, fsx);
34
+ export const uncommittedStateFingerprint = (cwd = process.cwd(), fsx, base = HEAD_BASELINE) => {
35
+ const fingerprint = base.kind === 'head' ? computeTreeFingerprint(cwd, fsx) : computeBaseFingerprint(cwd, base, fsx);
35
36
  if (fingerprint == null) {
36
37
  throw stop(`cannot compute ${UNCOMMITTED_STATE_FINGERPRINT} — not inside a git work tree (or a git probe failed); a record never carries a null tree digest (fail closed)`);
37
38
  }
@@ -60,9 +60,10 @@
60
60
  //
61
61
  // Writer: appends to the delegation ledger through the store's lock-serialized append (the store's
62
62
  // preflight is the single legality door — this module adds NO second validator). Never commits,
63
- // never runs a subscription CLI, spawns nothing but git READS — with ONE stated exception:
63
+ // never runs a subscription CLI, spawns nothing but git READS — with TWO stated exceptions:
64
64
  // `handoff-return` attests MAIN's index with `git write-tree`, which may write a tree OBJECT into
65
- // the odb and moves no ref (the same probe `land --prepare` itself uses). Dependency-free,
65
+ // the odb (the same probe `land --prepare` itself uses); checkpoint measurement writes the leaf's
66
+ // OWN temporary index and forced-add blob objects — never a ref, never the real index. Dependency-free,
66
67
  // Node >= 22. No side effects on import (the isDirectRun idiom).
67
68
 
68
69
  import { readFileSync, realpathSync, readlinkSync } from 'node:fs';
@@ -73,6 +74,7 @@ import {
73
74
  DELEGATION_SCHEMA_VERSION, STEP_CLASSES, OBSERVATION_PROVENANCE, RETURN_OUTCOMES,
74
75
  SESSION_ID_NULLABLE_OUTCOMES, checkDispatchContractForm, checkDispatchMintConsistency,
75
76
  contractDigest, canonicalDelegationDigest, computeNumerator, evaluateMetricEligibility,
77
+ HEAD_BASELINE, readsBaseline, isTreeOid,
76
78
  } from './dispatch-record.mjs';
77
79
  import {
78
80
  appendDelegationRecord, readDelegationStore, resolveDelegationStorePath, delegationThreadState,
@@ -86,7 +88,11 @@ import { execReceiptBasename, execReportBasename, parseExecReceipt } from './exe
86
88
  import {
87
89
  enumerateReturnedObjects, computeReturnedDiff, assembleIntegrationBundle,
88
90
  } from './exec-producer.mjs';
89
- import { gitBuf, isTreeClean } from './core-evidence.mjs';
91
+ import { gitBuf } from './core-evidence.mjs';
92
+ import { isCleanAgainstBase, resolveTreeObject } from './dispatch-baseline.mjs';
93
+ import { readDelegationLedger } from './dispatch-store-read.mjs';
94
+ import { judgeLedger, threadVerdict, HELD_RECEIPT_BACKEND } from './held-session.mjs';
95
+ import { degradeRecordSet, selectHeldSessionDegrades } from './review-state.mjs';
90
96
  import { lstatNoFollowRead, readRegularFileNoFollow, readFileBytesNoFollow } from './fs-read-nofollow.mjs';
91
97
  import { gitLine } from './flow-store-read.mjs';
92
98
  import {
@@ -98,7 +104,7 @@ const usageFail = (message) => Object.assign(new Error(message), { exitCode: 2 }
98
104
 
99
105
  // The ONE contract sentence, doc-parity-bound into references/modes/dispatch.md: the FORM-only limit
100
106
  // and the aggregator's refusals are what a reader must not be able to mis-learn from the mode doc.
101
- export const DISPATCH_CONTRACT = 'the contract check is FORM-only — fields present, grammars respected, never boundedness, design-decidedness or acceptance adequacy — and `aggregate` REFUSES instead of computing acceptance for a wave with no pre-registration record, over an OPEN thread in scope, over a PRE-DISPATCH degrade that opens no thread, or across several waves with no `--wave`; the writer verbs add NO second legality door — the store\'s preflight is the only one, and its refusals travel verbatim — while `open` copies every mint-time field from the contract header and refuses a deadline below the wrapper cap plus the kill grace, `return` absorbs only a TERMINAL exec receipt whose backend, nonce and independently computed contractDigest match the dispatch it answers, and `fold` binds the CURRENT tree to the folded return\'s postTreeDigest, so a tree that moved between the two never folds, and `await` is satisfied ONLY by the TERMINAL exec receipt of its own dispatch\'s {backend, nonce} — never by a review receipt, a ledger line or a finding manifest — while an expiry names a supervision question and releases NO writer slot';
107
+ export const DISPATCH_CONTRACT = 'the contract check is FORM-only — fields present, grammars respected, never boundedness, design-decidedness or acceptance adequacy — and `aggregate` REFUSES instead of computing acceptance for a wave with no pre-registration record, over an OPEN thread in scope, over a PRE-DISPATCH degrade that opens no thread, or across several waves with no `--wave`; the writer verbs add NO second legality door — the store\'s preflight is the only one, and its refusals travel verbatim — while `open` copies every mint-time field from the contract header and refuses a deadline below the wrapper cap plus the kill grace, `return` absorbs only a TERMINAL exec receipt whose backend, nonce and independently computed contractDigest match the dispatch it answers, and `fold` binds the CURRENT tree to the folded return\'s postTreeDigest, so a tree that moved between the two never folds, and `await` is satisfied ONLY by the TERMINAL exec receipt of its own dispatch\'s {backend, nonce} — never by a review receipt, a ledger line or a finding manifest — while an expiry names a supervision question and releases NO writer slot; `open` records the thread\'s BASE (`head` by default, `checkpoint` under `--checkpoint <oid>`), `return` and `fold` measure against the base the dispatch recorded, never a flag, and the `fold` VERB itself refuses a checkpoint `code` thread the held-session judge names SUBSTITUTED in that thread\'s own verdict — a precondition like its hidden-path and content-blind guards, the store\'s preflight staying the only door on the record';
102
108
 
103
109
  // ── the flag surface (the CLI tests pin it against the D3 key sets) ────────────────────────────────
104
110
  // flag → the record field it decides. The fields NOT on a flag are DERIVED and listed beside them,
@@ -138,6 +144,7 @@ export const OPEN_FLAG_FIELDS = Object.freeze({
138
144
  '--backend': 'backend',
139
145
  '--rationale': 'rationale',
140
146
  '--retry-of': 'retryOf',
147
+ '--checkpoint': 'baseline.treeOid',
141
148
  });
142
149
  // COPIED from the contract header at mint and bound by contractDigest (D3): a dispatch that
143
150
  // disagreed with the header it claims to carry is refused by checkDispatchMintConsistency.
@@ -525,7 +532,14 @@ const runOpen = ({ baseCwd, env, argv, now }) => {
525
532
  // and a verb should refuse in its own words before another module has to. Not decidable is never
526
533
  // CLEAN: baselineClean:false is what makes the eventual return honestly ineligible, and guessing
527
534
  // true would let an unattributable metric into the acceptance number.
528
- const baselineClean = isTreeClean(cwd);
535
+ const oid = values['--checkpoint'];
536
+ if (oid !== undefined) {
537
+ if (!isTreeOid(oid)) return refusal('open', `--checkpoint "${oid}" is not a git object id of exactly 40 or 64 lowercase hex characters; nothing was written`);
538
+ const resolved = resolveTreeObject(cwd, oid);
539
+ if (!resolved.ok) return refusal('open', resolved.reason);
540
+ }
541
+ const base = oid === undefined ? HEAD_BASELINE : { kind: 'checkpoint', treeOid: oid };
542
+ const baselineClean = isCleanAgainstBase(cwd, base);
529
543
  if (baselineClean === null) {
530
544
  return refusal('open', 'the working state could not be probed, so the baseline is undecidable — a dispatch never records a guessed baseline, and outside a git work tree there is no tree to fingerprint either (fail closed); nothing was written');
531
545
  }
@@ -539,12 +553,12 @@ const runOpen = ({ baseCwd, env, argv, now }) => {
539
553
  // with another run's evidence.
540
554
  const leftover = existingArtifactRefusal(dirname(resolveDelegationStorePath(cwd, env)), need(values, '--backend'), contract.nonce);
541
555
  if (leftover !== null) return refusal('open', `${leftover}; nothing was written`);
542
- // The baseline is a RECORDED CLAIM about this tree, so it is refused before it is made: a tree that
543
- // conceals a change reports CLEAN to `isTreeClean` and then hands the concealed change to the
556
+ // The baseline is a RECORDED CLAIM about this tree, so it is refused before it is made: under a head
557
+ // base a tree that conceals a change probes CLEAN and then hands the concealed change to the
544
558
  // delegate's account at return time. `open` is where that lie is cheapest to catch.
545
559
  const honest = hiddenFromPlainDiff(top);
546
560
  if (!honest.ok) return refusal('open', `${honest.reason}; nothing was written`);
547
- const preTreeDigest = uncommittedStateFingerprint(cwd);
561
+ const preTreeDigest = uncommittedStateFingerprint(cwd, undefined, base);
548
562
  const record = {
549
563
  schema: DELEGATION_SCHEMA_VERSION,
550
564
  kind: 'dispatch',
@@ -556,6 +570,7 @@ const runOpen = ({ baseCwd, env, argv, now }) => {
556
570
  contractDigest: contractDigest(contract),
557
571
  preTreeDigest,
558
572
  baselineClean,
573
+ baseline: { kind: base.kind, treeOid: base.treeOid },
559
574
  deadlineS: contract.deadlineS,
560
575
  retryOf: values['--retry-of'] ?? null,
561
576
  retryIndex: contract.retry.index,
@@ -576,7 +591,7 @@ const runOpen = ({ baseCwd, env, argv, now }) => {
576
591
  const { writtenPath } = appendDelegationRecord({ cwd, record, env });
577
592
  return {
578
593
  code: 0,
579
- stdout: `dispatch open: thread "${record.nonce}" opened in wave "${record.waveId}" — class ${record.stepClass} · backend ${record.backend} · vehicle ${record.vehicle.requested} → ${record.vehicle.selected} · deadline ${record.deadlineS}s (floor ${floorS}s) · retry ${record.retryIndex}/${record.retryCap} · baseline ${baselineClean ? 'CLEAN' : 'DIRTY — the return will be metric-INELIGIBLE (dirty-baseline)'} → ${writtenPath}`,
594
+ stdout: `dispatch open: thread "${record.nonce}" opened in wave "${record.waveId}" — class ${record.stepClass} · backend ${record.backend} · vehicle ${record.vehicle.requested} → ${record.vehicle.selected} · deadline ${record.deadlineS}s (floor ${floorS}s) · retry ${record.retryIndex}/${record.retryCap} · baseline ${baselineClean ? (base.kind === 'checkpoint' ? `CLEAN against checkpoint ${base.treeOid}` : 'CLEAN') : 'DIRTY — the return will be metric-INELIGIBLE (dirty-baseline)'} → ${writtenPath}`,
580
595
  stderr: '',
581
596
  };
582
597
  };
@@ -741,17 +756,9 @@ const runAwait = async ({ baseCwd, env, argv, now, sleep, pollMs }) => {
741
756
 
742
757
  // ── return: the wrapper's exec receipt, ABSORBED ──────────────────────────────────────────────────
743
758
 
744
- // The return-time guard the Phase-1 council required. `git diff` SKIPS index entries carrying
745
- // assume-unchanged or skip-worktree and honours diff.ignoreSubmodules, so a path can be CHANGED and
746
- // invisible to BOTH halves of the ratio at once — the producer's enumeration and the canonical
747
- // payload the denominator is framed from run the same plain probes. The kit already owns a probe
748
- // that sees them (computeWorkingState forces --ignore-submodules=none and folds in flaggedIndexLag),
749
- // so the absorb door compares the two views and refuses the DIFFERENCE by name.
750
- //
751
- // It is deliberately NOT a producer fix: D7 binds the numerator to computeFingerprintPayload's byte
752
- // domain, and forcing the flags on one side only would let the numerator count objects the
753
- // denominator cannot see — a worse failure than the blindness. The payload-side fix is queued as its
754
- // own frozen-shared-surface change.
759
+ // The return-time guard the Phase-1 council required. Under a head base `git diff` SKIPS index entries
760
+ // carrying assume-unchanged or skip-worktree, so a path can be CHANGED and invisible to the producer's
761
+ // enumeration and to the canonical payload alike — a tree that conceals a change is refused, never measured.
755
762
  //
756
763
  // The untracked section is excluded from the comparison because BOTH views read it with the same
757
764
  // `ls-files --others --exclude-standard` probe: there is no divergence there to find. Both sides
@@ -759,17 +766,18 @@ const runAwait = async ({ baseCwd, env, argv, now, sleep, pollMs }) => {
759
766
  // alone — and if it ever did, the answer would be a refusal, never a wrong number.
760
767
  // A tree can LIE about itself in two independent ways, and neither is decidable by comparing two
761
768
  // views that share the same blindness. So this asks two questions of its own, and every door that
762
- // measures or binds a tree (`open`, `return`, `fold`) asks them before it does anything else.
769
+ // measures or binds a tree (`open`, `return`, `fold`) asks them.
763
770
  //
764
771
  // (a) INDEX BITS, fail closed on their PRESENCE. `git ls-files -v` tags an assume-unchanged entry
765
- // lowercase and a skip-worktree entry `S`, and the second one is the sharp case: a MISSING
772
+ // lowercase and a skip-worktree entry `S`, and the second one is the sharp case: under a head base a MISSING
766
773
  // skip-worktree path is an ordinary sparse checkout to every probe this kit owns — probed live, the
767
774
  // deletion of a materialized skip-worktree file is invisible to `computeWorkingState`, to the plain
768
775
  // diff, to the tree fingerprint AND to the producer's enumeration. Nothing can compare its way to
769
776
  // that, so the BIT is refused rather than its effect. It bites hardest at `open`: set the bit, delete
770
777
  // the file, open (a FALSE clean baseline is recorded), then clear the bit — and the return credits the
771
778
  // delegate with a deletion it never made. Refusing any tag but `H` also refuses an unmerged index,
772
- // which is honest for a measurement.
779
+ // which is honest for a measurement; a checkpoint measurement sees the deletion because its scope
780
+ // names the path from the base tree.
773
781
  //
774
782
  // (b) The --ignore-submodules axis, PER SIDE and on BYTES. Against the UNION of the two name lists a
775
783
  // path visible on one side masks its own hidden state on the other; against DECODED names two
@@ -847,12 +855,12 @@ const canonicalStoreRefusal = (cwd, env) => {
847
855
  return null;
848
856
  };
849
857
 
850
- // A symlink's TARGET is read by the shared payload with `readlink` as a STRING, so bytes that are not
851
- // valid UTF-8 are gone before any framing question arises — probed, two links whose targets are the
852
- // single bytes 0xff and 0xfe produce the SAME payload and the SAME enumeration, so swapping one for
853
- // the other after a return is invisible to the fold. Until the payload reads targets as bytes (queued
854
- // with the framing migration), such a link is refused: this is not a fourth blind CLASS, it is the
855
- // narrow case where the payload provably cannot follow one object's bytes.
858
+ // Under a head base an UNTRACKED symlink's TARGET is read by the payload with `readlink` as a STRING, so bytes that
859
+ // are not valid UTF-8 are gone before any framing question arises — probed, two untracked links whose targets are the
860
+ // single bytes 0xff and 0xfe produce the SAME payload and the SAME enumeration, so swapping one for the other after a
861
+ // return is invisible to the fold. A TRACKED link's target rides `git diff` RAW, and a checkpoint payload carries it
862
+ // too, so this is not a fourth blind CLASS: it is the CONSERVATIVE refusal over the class, holding under either base
863
+ // by one rule, for the narrow case where the payload provably cannot follow one object's bytes.
856
864
  // ENOENT is the ONLY error that means "there is nothing to check here" — a deleted link, whose bytes
857
865
  // ride the diff exactly. EVERY other errno refuses, EINVAL emphatically included: the producer labels
858
866
  // an object `symlink` when ANY layer carries mode 120000, so a committed symlink REPLACED by a binary
@@ -876,7 +884,7 @@ const symlinkTargetRefusal = (top, entries, io = {}) => {
876
884
  if (!Buffer.from(target.toString('utf8'), 'utf8').equals(target)) lost.push(`${entry.path} -> 0x${target.toString('hex')}`);
877
885
  }
878
886
  if (lost.length === 0) return null;
879
- return `${lost.length} symlink target(s) are not valid UTF-8 (${lost.join(', ')}) — the shared payload reads a target as a STRING, so those bytes are folded to U+FFFD before the digest is taken and a later change of target moves nothing at all; this lane is fail-closed for them until the payload reads targets as bytes`;
887
+ return `${lost.length} symlink target(s) are not valid UTF-8 (${lost.join(', ')}) — refused conservatively: the head payload reads an UNTRACKED link's target as a STRING and folds those bytes to U+FFFD, so this lane is fail-closed for them under either base`;
880
888
  };
881
889
 
882
890
  // NUL-delimited git output, kept as BUFFER segments — a decoded split cannot be undone.
@@ -919,7 +927,7 @@ export const hiddenFromPlainDiff = (top) => {
919
927
  .filter((seg) => seg.length > 2 && String.fromCharCode(seg[0]) !== LS_FILES_CACHED_TAG)
920
928
  .map((seg) => `${String.fromCharCode(seg[0])} ${showPath(seg.subarray(2))}`);
921
929
  if (flagged.length > 0) {
922
- return { ok: false, reason: `${flagged.length} index entr(ies) carry a tag other than "${LS_FILES_CACHED_TAG}" (${flagged.join('; ')}) — an assume-unchanged or skip-worktree entry makes the index lie about the worktree, and the sharpest case is invisible to EVERY probe this kit owns: deleting a materialized skip-worktree file changes no diff, no fingerprint and no enumeration, so a delegated measurement over such a tree is not honest at all; clear the bits (git update-index --no-assume-unchanged / --no-skip-worktree) and try again` };
930
+ return { ok: false, reason: `${flagged.length} index entr(ies) carry a tag other than "${LS_FILES_CACHED_TAG}" (${flagged.join('; ')}) — an assume-unchanged or skip-worktree entry makes the index lie about the worktree, and under a head base the sharpest case is invisible to EVERY probe this kit owns: deleting a materialized skip-worktree file changes no diff, no fingerprint and no enumeration, so a delegated measurement over such a tree is not honest at all; clear the bits (git update-index --no-assume-unchanged / --no-skip-worktree) and try again` };
923
931
  }
924
932
  const key = (seg) => seg.toString('latin1');
925
933
  const missing = (forced, plain) => {
@@ -936,15 +944,16 @@ export const hiddenFromPlainDiff = (top) => {
936
944
  hiddenStaged.length > 0 ? `staged: ${hiddenStaged.map(showPath).join(', ')}` : null,
937
945
  hiddenUnstaged.length > 0 ? `unstaged: ${hiddenUnstaged.map(showPath).join(', ')}` : null,
938
946
  ].filter((part) => part !== null).join('; ');
939
- return { ok: false, reason: `${count} changed path(s) are HIDDEN from the plain git diff this metric is computed over (${where}) — an ignore-submodules setting keeps them out of BOTH the numerator and the denominator, so the recorded bytes would describe a change set that is not the one on disk; clear the diff config and try again` };
947
+ return { ok: false, reason: `${count} changed path(s) are HIDDEN from the plain git diff the head-base metric is computed over (${where}) — clear the diff config and try again` };
940
948
  };
941
949
 
942
950
  // THE CONTENT-BLIND CLASSES, and the line between them and the merely ambiguous ones.
943
951
  //
944
- // For three kinds the payload carries NO CONTENT AT ALL, so their bytes can move underneath a digest
945
- // that cannot follow them — all three probed live:
946
- // • `binary` — the payload holds `untracked-binary:<path>`, and a tracked binary's diff is the one
947
- // line "Binary files … differ". Neither a same-size mutation nor a SIZE change moves the digest.
952
+ // Under a head base, for three kinds the payload cannot be trusted to follow an object's bytes, so they can move
953
+ // underneath a digest — each arm probed live, and two of the three are CONSERVATIVE over their whole class:
954
+ // • `binary` — an UNTRACKED one reaches the payload as `untracked-binary:<path>`, its name alone, so
955
+ // neither a same-size mutation nor a SIZE change moves the digest; a TRACKED one's diff carries
956
+ // both blob ids on its `index` line, so that half IS followed and the refusal is the conservative one.
948
957
  // • `non-regular` — `untracked-nonregular:<path>`, a name and nothing else.
949
958
  // • `submodule` — the first transition to dirty moves the digest (the superproject line gains
950
959
  // "-dirty") and NOTHING after it does: a second, different nested edit and a whole new nested
@@ -954,11 +963,11 @@ export const hiddenFromPlainDiff = (top) => {
954
963
  // is SUBTRACTED: a change set carrying one is refused, by name, at both doors.
955
964
  //
956
965
  // Regular-file content and a symlink's TARGET are deliberately NOT here. They are present in the
957
- // payload — only unframed, so adjacent entries can alias each other (the residual named in the mode
966
+ // payload — under a head base only unframed, so adjacent entries can alias each other (the residual named in the mode
958
967
  // doc and in --help). Subtracting them would refuse `new` and `symlink`, which is every delegated
959
968
  // change set there is, and the lane would measure nothing at all.
960
969
  //
961
- // Restoring the three means changing `computeFingerprintPayload` — a Plan-1 frozen surface the
970
+ // Restoring the three under a head base means changing `computeFingerprintPayload` — a Plan-1 frozen surface the
962
971
  // REVIEW lane also binds — which is queued, not done here.
963
972
  export const CONTENT_BLIND_KINDS = Object.freeze(['binary', 'non-regular', 'submodule']);
964
973
 
@@ -966,7 +975,7 @@ export const CONTENT_BLIND_KINDS = Object.freeze(['binary', 'non-regular', 'subm
966
975
  // clean staged gitlink replacement carries exact OIDs in the payload; it is the nested state of an
967
976
  // already-DIRTY one that becomes invisible, and no cheap probe separates the two at this door.
968
977
  const CONTENT_BLIND_WHY = {
969
- binary: 'the payload holds its name only, so neither its content nor its size reaches the digest',
978
+ binary: 'refused conservatively: an untracked binary reaches the head payload as its name only, so neither its content nor its size reaches its digest',
970
979
  'non-regular': 'the payload holds its name only',
971
980
  submodule: 'refused conservatively: a clean pointer change does carry its OIDs, but once the submodule is dirty the payload records nothing further about its nested state',
972
981
  };
@@ -975,7 +984,7 @@ export const contentBlindRefusal = (entries) => {
975
984
  const blind = entries.filter((e) => CONTENT_BLIND_KINDS.includes(e.kind));
976
985
  if (blind.length === 0) return null;
977
986
  const listed = blind.map((e) => `${e.kind} ${e.path} (${CONTENT_BLIND_WHY[e.kind]})`).join('; ');
978
- return `the change set carries ${blind.length} object(s) whose CONTENT never enters the uncommitted-state payload (${listed}) — their bytes can move under a tree digest that cannot follow them, so the numerator would count a size the fold's binding cannot re-confirm. This lane is fail-closed for them until the shared payload can carry their content (a frozen surface the review lane binds too): keep such objects out of a measured dispatch, or close the thread with degrade`;
987
+ return `the change set carries ${blind.length} object(s) this lane will not measure (${listed}) — refused CONSERVATIVELY over the class, because for a blind one the bytes can move under a tree digest that cannot follow them and the numerator would count a size the fold's binding cannot re-confirm. This lane, under either base, is fail-closed for them until the shared payload can carry their content (a frozen surface the review lane binds too): keep such objects out of a measured dispatch, or close the thread with degrade`;
979
988
  };
980
989
 
981
990
  // Pre-spend: neither artifact name may be taken before the dispatch that will own it exists. The
@@ -1126,14 +1135,15 @@ const runReturn = ({ baseCwd, env, argv, now }) => {
1126
1135
  // fingerprint is taken before the walks and the payload's own digest is compared against it after.
1127
1136
  // A tree that moved between them would hand the numerator one change set and the denominator
1128
1137
  // another, and the record would bind a postTreeDigest neither of them describes.
1129
- const openingDigest = uncommittedStateFingerprint(cwd);
1130
- const enumerated = enumerateReturnedObjects(cwd);
1138
+ const base = readsBaseline(dispatch);
1139
+ const openingDigest = uncommittedStateFingerprint(cwd, undefined, base);
1140
+ const enumerated = enumerateReturnedObjects(cwd, { base });
1131
1141
  if (!enumerated.ok) return refusal('return', enumerated.reason);
1132
1142
  const opaque = contentBlindRefusal(enumerated.entries);
1133
1143
  if (opaque !== null) return refusal('return', `${opaque}; nothing was written`);
1134
1144
  const lostTarget = symlinkTargetRefusal(top, enumerated.entries);
1135
1145
  if (lostTarget !== null) return refusal('return', `${lostTarget}; nothing was written`);
1136
- const produced = computeReturnedDiff(cwd);
1146
+ const produced = computeReturnedDiff(cwd, { base });
1137
1147
  if (!produced.ok) return refusal('return', produced.reason);
1138
1148
  // The payload IS the diff and its digest IS the uncommitted-state fingerprint — one computation,
1139
1149
  // so diffDigest and postTreeDigest are equal by construction rather than by coincidence.
@@ -1251,7 +1261,7 @@ const runFold = ({ baseCwd, env, argv, now }) => {
1251
1261
  return refusal('fold', `nonce "${nonce}" carries no return to fold — a fold folds a RETURN, and the thread's last record is a ${state.last.kind}; nothing was written`);
1252
1262
  }
1253
1263
  // THE SAME hidden-path guard the absorb door runs, and for a sharper reason: `treeDigestAtFold` is
1254
- // computed from the very payload that is blind to these paths, so a change made behind an index bit
1264
+ // computed from the very payload that is blind to these paths, so under a head base a change made behind an index bit
1255
1265
  // between the return and the fold leaves the digest EQUAL and the fold would accept bytes nobody
1256
1266
  // returned. The digest cannot catch what the payload cannot see; this guard is what does.
1257
1267
  const hidden = hiddenFromPlainDiff(top);
@@ -1259,30 +1269,45 @@ const runFold = ({ baseCwd, env, argv, now }) => {
1259
1269
  // …and the same subtraction: an object the payload holds by name alone can be mutated between the
1260
1270
  // return and the fold without moving the digest this fold is about to bind. The enumeration runs
1261
1271
  // here for that one question — the fold computes no metric of its own.
1262
- const enumerated = enumerateReturnedObjects(cwd);
1272
+ const base = readsBaseline(state.dispatch);
1273
+ const enumerated = enumerateReturnedObjects(cwd, { base });
1263
1274
  if (!enumerated.ok) return refusal('fold', enumerated.reason);
1264
1275
  const opaque = contentBlindRefusal(enumerated.entries);
1265
1276
  if (opaque !== null) return refusal('fold', `${opaque}; nothing was written`);
1266
1277
  const lostTarget = symlinkTargetRefusal(top, enumerated.entries);
1267
1278
  if (lostTarget !== null) return refusal('fold', `${lostTarget}; nothing was written`);
1268
- // WHAT THIS BINDING IS, exactly: EQUALITY OF THE VISIBLE UNFRAMED PAYLOAD between the return and
1269
- // the fold — never an identity of the tree, and the difference is not academic. The payload is an
1279
+ if (state.dispatch.stepClass === 'code' && base.kind === 'checkpoint') {
1280
+ const evidence = degradeRecordSet({ cwd, env, fingerprint: null });
1281
+ const facts = judgeLedger(readDelegationLedger(cwd, env), {
1282
+ backend: HELD_RECEIPT_BACKEND, degrades: selectHeldSessionDegrades(evidence.records),
1283
+ });
1284
+ if (facts.state === 'error') return refusal('fold', `${facts.reason} (fail closed); nothing was written`);
1285
+ const thread = threadVerdict(facts, nonce);
1286
+ if (thread?.substituted) {
1287
+ const unavailable = evidence.unavailable ? ' (the evidence store is unavailable: judged with no degrade record)' : '';
1288
+ return refusal('fold', `refusing to fold thread "${nonce}": a checkpoint-based code thread whose return rode session "${thread.actualId}" while the held session it was opened against was "${thread.expectedId}" — record its ledger degrade (dispatch degrade --wave ${state.dispatch.waveId} --nonce ${nonce} --step-class code --rationale "..."), then retry it (cap permitting) or open a new thread on the held session, and fold that; nothing was written${unavailable}`);
1289
+ }
1290
+ }
1291
+ // WHAT THIS BINDING IS, exactly: EQUALITY OF THE VISIBLE PAYLOAD between the return and
1292
+ // the fold — never an identity of the tree. Under a HEAD base the payload is an
1270
1293
  // unframed concatenation, so two DIFFERENT trees can produce the same bytes: probed live, one file
1271
1294
  // containing the line `untracked:two.txt` yields the same fingerprint as a tree of two files, and a
1272
- // symlink target can imitate the marker that opens the next untracked entry. It also carries no
1273
- // git-relevant mode, so making an untracked file executable moves nothing at all. Those are stated
1295
+ // symlink target can imitate the marker that opens the next untracked entry. Its UNTRACKED section
1296
+ // carries no git-relevant mode either, so making an untracked file executable moves nothing at all. Those are stated
1274
1297
  // residual limits of a Plan-1 frozen surface the review lane binds too, queued as its own item —
1275
- // not defects of this verb, and not something this verb may quietly claim away.
1298
+ // not defects of this verb, and not something this verb may quietly claim away. Under a checkpoint
1299
+ // base the payload is one indexed diff: a mode change moves it and no untracked marker line exists.
1276
1300
  //
1277
1301
  // Within that domain the binding does its job: a tree whose payload moved between the return and
1278
- // the fold refuses, and the recovery is a fresh dispatch. Staging usually moves the payload — every
1302
+ // the fold refuses, and the recovery is a fresh dispatch. Under a HEAD base staging usually moves the payload — every
1279
1303
  // change set carrying an untracked path does — which is why the fold precedes `git add -A` (D16).
1280
1304
  // The one shape it does not move is a tracked-only change passing from the worktree into a CLEAN
1281
1305
  // index: the payload concatenates the staged and unstaged diffs, so those bytes are identical
1282
1306
  // either side of `git add` (the fingerprint's stated blindness to the index↔worktree split). The
1283
1307
  // fold is honest there — identical payload bytes, identical content — so the rule is "the fold
1284
- // precedes staging", never "staging refuses the fold by construction".
1285
- const treeDigestAtFold = uncommittedStateFingerprint(cwd);
1308
+ // precedes staging", never "staging refuses the fold by construction". A checkpoint measurement
1309
+ // never reads the real index, so staging moves nothing there; the fold still precedes `git add`.
1310
+ const treeDigestAtFold = uncommittedStateFingerprint(cwd, undefined, base);
1286
1311
  const record = {
1287
1312
  schema: DELEGATION_SCHEMA_VERSION,
1288
1313
  kind: 'fold',
@@ -1575,7 +1600,7 @@ Usage:
1575
1600
  [--denominator-bytes <n>] [--cwd <dir>]
1576
1601
  node dispatch.mjs open --contract <dispatch-file> --wave <id> --backend <name>
1577
1602
  --rationale <text> --wrapper-cap-s <n> --kill-grace-s <n>
1578
- [--retry-of <nonce>] [--cwd <dir>]
1603
+ [--checkpoint <oid>] [--retry-of <nonce>] [--cwd <dir>]
1579
1604
  node dispatch.mjs await --nonce <n> [--timeout <s>] [--cwd <dir>]
1580
1605
  node dispatch.mjs return --nonce <n> [--outcome <o>]
1581
1606
  [--no-receipt --exit-status <n>] [--cwd <dir>]
@@ -1624,6 +1649,9 @@ dirty one is recorded, which makes the eventual return metric-INELIGIBLE by name
1624
1649
  deadlineS below --wrapper-cap-s plus --kill-grace-s (both explicit — the kit never reads another
1625
1650
  package's default), REFUSES a tree that conceals a change (below), and surfaces every retry and wave
1626
1651
  refusal from the store verbatim.
1652
+ --checkpoint <oid> records a resolvable TREE object of exactly 40 or 64 lowercase hex characters
1653
+ (a commit, blob, tag or unknown id refuses by name); the base rides the record and return/fold read
1654
+ it there, while a checkpoint CLEAN line names the base.
1627
1655
 
1628
1656
  THE LEDGER a tree-binding verb uses is the CANONICAL one, exactly: <git common dir>/
1629
1657
  agent-workflow-delegation.jsonl. A store inside the work tree is measured as part of the change set
@@ -1649,7 +1677,7 @@ without an answer never authorizes the next dispatch.
1649
1677
  A CONCEALING TREE is refused at every door that measures or binds one (open, return, fold), because
1650
1678
  the recorded baseline, the counted bytes and the folded identity are all claims about a tree that is
1651
1679
  telling the truth. Two arms: any index entry whose ls-files tag is not "H" refuses on the BIT's
1652
- presence — deleting a materialized skip-worktree file is invisible to every probe this kit owns, so
1680
+ presence — under a head base deleting a materialized skip-worktree file is invisible to every probe this kit owns, so
1653
1681
  its effect cannot be compared for — and a per-side, BYTE-keyed comparison of the forced against the
1654
1682
  plain diff refuses a path an ignore-submodules setting hides. Both name the path; the recovery is
1655
1683
  git update-index --no-assume-unchanged / --no-skip-worktree, or clearing the diff config.
@@ -1659,7 +1687,7 @@ the TERMINAL receipt (a RESERVED one is a supervision question, never a timeout)
1659
1687
  receipt's independently computed contractDigest, its {backend, nonce}, its capS+killGraceS against
1660
1688
  the recorded deadlineS and its timestamp against the ABSOLUTE deadline (the dispatch's timestamp plus
1661
1689
  deadlineS), re-verifies the report's digest and length, refuses a change set HIDDEN from the plain
1662
- git diff the metric is computed over (assume-unchanged, skip-worktree, ignore-submodules), and then
1690
+ git diff the head-base metric is computed over (assume-unchanged, skip-worktree, ignore-submodules), and then
1663
1691
  enumerates the returned objects and frames the canonical integration bundle — bracketed by the tree
1664
1692
  fingerprint, so a tree that moves mid-computation refuses instead of mixing two change sets.
1665
1693
  --outcome records an orchestrator judgment under the closed override form: a wrapper outcome either
@@ -1674,19 +1702,24 @@ diff, and no-op-diff where the tree is unchanged too, since the eligibility rule
1674
1702
  first. With no artifact at all there is no honest return: close the thread with degrade.
1675
1703
 
1676
1704
  fold appends the integration re-confirmation and CLOSES the thread. It runs the same hidden-path
1677
- guard as return — a change made behind an index bit leaves the tree digest EQUAL, so the digest alone
1705
+ guard as return — under a head base a change made behind an index bit leaves the tree digest EQUAL, so the digest alone
1678
1706
  cannot catch it — then computes the CURRENT tree digest, which the store binds to the folded return's
1679
- postTreeDigest. What that binding IS, exactly: equality of the VISIBLE UNFRAMED PAYLOAD, never an
1680
- identity of the tree. The payload is an unframed concatenation, so two different trees can produce
1707
+ postTreeDigest. What that binding IS, exactly: equality of the VISIBLE PAYLOAD, never an
1708
+ identity of the tree. Under a HEAD base the payload is an unframed concatenation, so two different trees can produce
1681
1709
  the same bytes (a file's content or a symlink's target can imitate the marker line that opens the
1682
- next untracked entry), and it carries no git-relevant mode, so making an untracked file executable
1710
+ next untracked entry), and its UNTRACKED section carries no git-relevant mode, so making an untracked file executable
1683
1711
  moves nothing. Those residuals belong to a frozen shared surface and are queued, not claimed away
1684
- here. Within that domain a tree whose payload moved refuses, and the recovery is a fresh dispatch,
1685
- never a fold. Staging usually moves the payload (every change set carrying an untracked path does),
1712
+ here. Under a checkpoint base the payload is one indexed diff: a mode change moves it and no untracked
1713
+ marker line exists. Within that domain a tree whose payload moved refuses, and the recovery is a fresh dispatch,
1714
+ never a fold. Under a HEAD base staging usually moves the payload (every change set carrying an untracked path does),
1686
1715
  so the fold precedes git add. The one shape staging does NOT move is a tracked-only change passing
1687
1716
  into a CLEAN index — the payload concatenates the staged and unstaged diffs, so those bytes are
1688
1717
  identical either side of git add. The fold stays honest there (same bytes, same content), which is
1689
1718
  why the rule is "fold before staging", not "staging refuses the fold".
1719
+ A checkpoint measurement never reads the real index, so staging moves nothing there; the fold still
1720
+ precedes git add. Before binding the digest, fold refuses a checkpoint code thread whose own
1721
+ held-session verdict is SUBSTITUTED, naming its ledger degrade and retry as recovery, and fails
1722
+ closed on an error epoch or an unreadable ledger.
1690
1723
 
1691
1724
  degrade appends the recorded no-fold closure, threaded (with --nonce) or PRE-DISPATCH (without). The
1692
1725
  pre-dispatch form opens no nonce thread, so aggregate REFUSES the whole wave by name once one is
@@ -1734,19 +1767,25 @@ directory, named agent-workflow-exec-receipt-<backendLength>-<backend>-<nonce>.j
1734
1767
  agent-workflow-exec-report-<backendLength>-<backend>-<nonce>.txt. Honest v1 limits: gate output is
1735
1768
  never accounted (the wrapper's exit trap removes its trace, so no gate-output component is emitted);
1736
1769
  a change set carrying a BINARY, non-regular or SUBMODULE object is REFUSED, because the shared
1737
- payload carries no content for those — a binary by name only, a submodule nothing beyond its first
1738
- dirty transition — so their bytes can move under a digest that cannot follow them, and the lane is
1739
- fail-closed for them until that frozen payload can carry it. STATED RESIDUALS on what it does accept:
1740
- the payload is UNFRAMED, so a file's content or a symlink's target can imitate the marker line that
1741
- opens the next untracked entry and two different trees can share one fingerprint, and no
1742
- git-relevant MODE is carried, so making an untracked file executable moves nothing — both are queued
1743
- against the payload, not claimed away here. A receipt is forgeable exactly like every record here;
1770
+ head payload cannot be trusted to follow their bytes — an untracked binary by name only, a submodule
1771
+ nothing beyond its first dirty transition — so their bytes can move under a digest that cannot follow
1772
+ them, and the lane is fail-closed for them until that frozen payload can carry it; the binary and
1773
+ submodule arms are CONSERVATIVE over their class. STATED RESIDUALS on what it does accept:
1774
+ under a HEAD base the payload is UNFRAMED, so a file's content or a symlink's target can imitate the marker line that
1775
+ opens the next untracked entry and two different trees can share one fingerprint, and that section
1776
+ carries no git-relevant MODE, so making an untracked file executable moves nothing — both are queued
1777
+ against the head payload, not claimed away here. Under a checkpoint base the payload is one indexed
1778
+ diff: a mode change moves it and no untracked marker line exists. Under a head base a delegate's rename
1779
+ arrives as a deletion plus a creation, over-counting a plain rename; under a checkpoint base git's own
1780
+ rename detection applies inside the one base-relative layer and a detected rename is counted once.
1781
+ A receipt is forgeable exactly like every record here;
1744
1782
  and D10 stands as a BAR, not a mechanism — at most one in-tree exec dispatch at a time, and nothing
1745
1783
  refuses a second.
1746
1784
 
1747
- Never commits, never runs a subscription CLI, spawns nothing but git READS — except handoff-return,
1785
+ Never commits, never runs a subscription CLI, spawns nothing but git READS — with TWO stated exceptions: handoff-return,
1748
1786
  which attests MAIN's index with git write-tree: that may write a tree OBJECT into the odb and moves
1749
- no ref (the same probe land --prepare itself uses). Exit codes: 0 success;
1787
+ no ref (the same probe land --prepare itself uses); checkpoint measurement writes the leaf's OWN
1788
+ temporary index file and forced-add blob objects — never a ref, never the real index. Exit codes: 0 success;
1750
1789
  1 a refusal (store STOP verbatim, a form violation, an unreadable file, a supervision question); 2
1751
1790
  usage; ${AWAIT_UNANSWERED_STATUS} an await that ended with no terminal receipt (the absolute deadline or the --timeout
1752
1791
  bound) — its own status so a caller that BRANCHES on the code can tell it from a refusal; a caller