@telora/daemon 0.23.16 → 0.23.18

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.
Files changed (165) hide show
  1. package/build-info.json +2 -2
  2. package/dist/ci/candidate-ref.d.ts +13 -0
  3. package/dist/ci/candidate-ref.d.ts.map +1 -1
  4. package/dist/ci/candidate-ref.js +18 -0
  5. package/dist/ci/candidate-ref.js.map +1 -1
  6. package/dist/completion/review-exit/review-census-record.d.ts +16 -2
  7. package/dist/completion/review-exit/review-census-record.d.ts.map +1 -1
  8. package/dist/completion/review-exit/review-census-record.js +23 -2
  9. package/dist/completion/review-exit/review-census-record.js.map +1 -1
  10. package/dist/completion/review-exit/review-exit-phase.d.ts +6 -0
  11. package/dist/completion/review-exit/review-exit-phase.d.ts.map +1 -1
  12. package/dist/completion/review-exit/review-exit-phase.js.map +1 -1
  13. package/dist/completion/state-cascade/settle-injection-sweep.d.ts.map +1 -1
  14. package/dist/completion/state-cascade/settle-injection-sweep.js +2 -1
  15. package/dist/completion/state-cascade/settle-injection-sweep.js.map +1 -1
  16. package/dist/completion/team-outcome/decide-shared.d.ts +3 -1
  17. package/dist/completion/team-outcome/decide-shared.d.ts.map +1 -1
  18. package/dist/completion/team-outcome/decide-shared.js +14 -3
  19. package/dist/completion/team-outcome/decide-shared.js.map +1 -1
  20. package/dist/completion/team-outcome/team-outcome.d.ts +14 -0
  21. package/dist/completion/team-outcome/team-outcome.d.ts.map +1 -1
  22. package/dist/completion/team-outcome/team-outcome.js +18 -0
  23. package/dist/completion/team-outcome/team-outcome.js.map +1 -1
  24. package/dist/composition/execution-merge-context.d.ts +7 -1
  25. package/dist/composition/execution-merge-context.d.ts.map +1 -1
  26. package/dist/composition/execution-merge-context.js +42 -6
  27. package/dist/composition/execution-merge-context.js.map +1 -1
  28. package/dist/composition/execution-recovery-context.d.ts.map +1 -1
  29. package/dist/composition/execution-recovery-context.js +2 -0
  30. package/dist/composition/execution-recovery-context.js.map +1 -1
  31. package/dist/composition/state-cascade-context.d.ts.map +1 -1
  32. package/dist/composition/state-cascade-context.js +8 -3
  33. package/dist/composition/state-cascade-context.js.map +1 -1
  34. package/dist/composition/verification-context.d.ts.map +1 -1
  35. package/dist/composition/verification-context.js +2 -0
  36. package/dist/composition/verification-context.js.map +1 -1
  37. package/dist/daemon-state/focus-team-state.d.ts +2 -0
  38. package/dist/daemon-state/focus-team-state.d.ts.map +1 -1
  39. package/dist/daemon-state/focus-team-state.js +6 -1
  40. package/dist/daemon-state/focus-team-state.js.map +1 -1
  41. package/dist/daemon-state/lead-process-ownership.d.ts.map +1 -1
  42. package/dist/daemon-state/lead-process-ownership.js +1 -0
  43. package/dist/daemon-state/lead-process-ownership.js.map +1 -1
  44. package/dist/daemon-state/provider-window.d.ts.map +1 -1
  45. package/dist/daemon-state/provider-window.js +1 -0
  46. package/dist/daemon-state/provider-window.js.map +1 -1
  47. package/dist/focus/crash-recovery.d.ts +7 -0
  48. package/dist/focus/crash-recovery.d.ts.map +1 -1
  49. package/dist/focus/crash-recovery.js +26 -13
  50. package/dist/focus/crash-recovery.js.map +1 -1
  51. package/dist/git/merge-lock.d.ts.map +1 -1
  52. package/dist/git/merge-lock.js +3 -1
  53. package/dist/git/merge-lock.js.map +1 -1
  54. package/dist/merge/candidate-rework.d.ts +3 -3
  55. package/dist/merge/candidate-rework.d.ts.map +1 -1
  56. package/dist/merge/candidate-rework.js +30 -10
  57. package/dist/merge/candidate-rework.js.map +1 -1
  58. package/dist/merge/completion-hold-record.d.ts +16 -0
  59. package/dist/merge/completion-hold-record.d.ts.map +1 -1
  60. package/dist/merge/completion-hold-record.js +60 -1
  61. package/dist/merge/completion-hold-record.js.map +1 -1
  62. package/dist/merge/completion-judge.d.ts +44 -0
  63. package/dist/merge/completion-judge.d.ts.map +1 -0
  64. package/dist/merge/completion-judge.js +36 -0
  65. package/dist/merge/completion-judge.js.map +1 -0
  66. package/dist/merge/completion-local-judge.d.ts +90 -0
  67. package/dist/merge/completion-local-judge.d.ts.map +1 -0
  68. package/dist/merge/completion-local-judge.js +193 -0
  69. package/dist/merge/completion-local-judge.js.map +1 -0
  70. package/dist/merge/completion-merge-driver.d.ts +31 -7
  71. package/dist/merge/completion-merge-driver.d.ts.map +1 -1
  72. package/dist/merge/completion-merge-driver.js +36 -8
  73. package/dist/merge/completion-merge-driver.js.map +1 -1
  74. package/dist/merge/completion-merge-gate.d.ts +10 -2
  75. package/dist/merge/completion-merge-gate.d.ts.map +1 -1
  76. package/dist/merge/completion-merge-gate.js +65 -19
  77. package/dist/merge/completion-merge-gate.js.map +1 -1
  78. package/dist/merge/merge-back-loop.d.ts +9 -1
  79. package/dist/merge/merge-back-loop.d.ts.map +1 -1
  80. package/dist/merge/merge-back-loop.js +28 -1
  81. package/dist/merge/merge-back-loop.js.map +1 -1
  82. package/dist/nexus/file-escalation.d.ts.map +1 -1
  83. package/dist/nexus/file-escalation.js +1 -0
  84. package/dist/nexus/file-escalation.js.map +1 -1
  85. package/dist/queries/api-client/shared.js +1 -1
  86. package/dist/queries/verification/verification.d.ts +8 -0
  87. package/dist/queries/verification/verification.d.ts.map +1 -1
  88. package/dist/queries/verification/verification.js +11 -1
  89. package/dist/queries/verification/verification.js.map +1 -1
  90. package/dist/spawn/codex-limit.d.ts +20 -4
  91. package/dist/spawn/codex-limit.d.ts.map +1 -1
  92. package/dist/spawn/codex-limit.js +36 -7
  93. package/dist/spawn/codex-limit.js.map +1 -1
  94. package/dist/spawn/helpers.d.ts.map +1 -1
  95. package/dist/spawn/helpers.js +13 -6
  96. package/dist/spawn/helpers.js.map +1 -1
  97. package/dist/spawn/model-reached.d.ts +6 -0
  98. package/dist/spawn/model-reached.d.ts.map +1 -1
  99. package/dist/spawn/model-reached.js +8 -0
  100. package/dist/spawn/model-reached.js.map +1 -1
  101. package/dist/spawn/next-spawn-cooldown.d.ts.map +1 -1
  102. package/dist/spawn/next-spawn-cooldown.js +2 -1
  103. package/dist/spawn/next-spawn-cooldown.js.map +1 -1
  104. package/dist/supervision/spawn-cooldown.d.ts +10 -1
  105. package/dist/supervision/spawn-cooldown.d.ts.map +1 -1
  106. package/dist/supervision/spawn-cooldown.js +3 -2
  107. package/dist/supervision/spawn-cooldown.js.map +1 -1
  108. package/dist/testing/fixtures/api-client.js +1 -1
  109. package/dist/testing/fixtures/codex-stream-session.d.ts.map +1 -1
  110. package/dist/testing/fixtures/codex-stream-session.js +1 -0
  111. package/dist/testing/fixtures/codex-stream-session.js.map +1 -1
  112. package/dist/testing/fixtures/completion-event-deps.js +1 -1
  113. package/dist/testing/fixtures/completion-judge-stubs.d.ts +15 -0
  114. package/dist/testing/fixtures/completion-judge-stubs.d.ts.map +1 -0
  115. package/dist/testing/fixtures/completion-judge-stubs.js +32 -0
  116. package/dist/testing/fixtures/completion-judge-stubs.js.map +1 -0
  117. package/dist/testing/fixtures/exit-capture-verify.d.ts +1 -0
  118. package/dist/testing/fixtures/exit-capture-verify.d.ts.map +1 -1
  119. package/dist/testing/fixtures/exit-capture-verify.js +3 -1
  120. package/dist/testing/fixtures/exit-capture-verify.js.map +1 -1
  121. package/dist/testing/fixtures/index.js +1 -1
  122. package/dist/testing/fixtures/process-close-context.d.ts.map +1 -1
  123. package/dist/testing/fixtures/process-close-context.js +1 -0
  124. package/dist/testing/fixtures/process-close-context.js.map +1 -1
  125. package/dist/testing/fixtures/review-exit-deps.js +1 -1
  126. package/dist/testing/fixtures/verification-deps.d.ts +6 -0
  127. package/dist/testing/fixtures/verification-deps.d.ts.map +1 -1
  128. package/dist/testing/fixtures/verification-deps.js +11 -0
  129. package/dist/testing/fixtures/verification-deps.js.map +1 -1
  130. package/dist/types/focus-team-state.d.ts +16 -2
  131. package/dist/types/focus-team-state.d.ts.map +1 -1
  132. package/dist/types/focus-team-state.js.map +1 -1
  133. package/dist/types/index.js +1 -1
  134. package/dist/verify/deterministic-gate/verification-checkout.d.ts.map +1 -1
  135. package/dist/verify/deterministic-gate/verification-checkout.js +1 -0
  136. package/dist/verify/deterministic-gate/verification-checkout.js.map +1 -1
  137. package/dist/verify/deterministic-gate/verification-deterministic.d.ts.map +1 -1
  138. package/dist/verify/deterministic-gate/verification-deterministic.js +1 -0
  139. package/dist/verify/deterministic-gate/verification-deterministic.js.map +1 -1
  140. package/dist/verify/effect-reconciliation/injection-stamp.d.ts +33 -18
  141. package/dist/verify/effect-reconciliation/injection-stamp.d.ts.map +1 -1
  142. package/dist/verify/effect-reconciliation/injection-stamp.js +154 -82
  143. package/dist/verify/effect-reconciliation/injection-stamp.js.map +1 -1
  144. package/dist/verify/effect-reconciliation/pending-injection-stamp.d.ts +36 -0
  145. package/dist/verify/effect-reconciliation/pending-injection-stamp.d.ts.map +1 -0
  146. package/dist/verify/effect-reconciliation/pending-injection-stamp.js +157 -0
  147. package/dist/verify/effect-reconciliation/pending-injection-stamp.js.map +1 -0
  148. package/dist/verify/effect-reconciliation/verify-restatement.js +1 -1
  149. package/dist/verify/engine/verification-deps.d.ts +10 -1
  150. package/dist/verify/engine/verification-deps.d.ts.map +1 -1
  151. package/dist/verify/engine/verification-deps.js +1 -1
  152. package/dist/verify/engine/verification-engine.js +8 -8
  153. package/dist/verify/engine/verification-engine.js.map +1 -1
  154. package/dist/verify/gate-config/verification-manifest.d.ts +21 -1
  155. package/dist/verify/gate-config/verification-manifest.d.ts.map +1 -1
  156. package/dist/verify/gate-config/verification-manifest.js +25 -1
  157. package/dist/verify/gate-config/verification-manifest.js.map +1 -1
  158. package/dist/verify/run-selection/verification-default-on.d.ts +2 -0
  159. package/dist/verify/run-selection/verification-default-on.d.ts.map +1 -1
  160. package/dist/verify/run-selection/verification-default-on.js +1 -1
  161. package/dist/verify/run-selection/verification-default-on.js.map +1 -1
  162. package/dist/worktree/focus-worktree-state.d.ts.map +1 -1
  163. package/dist/worktree/focus-worktree-state.js +1 -0
  164. package/dist/worktree/focus-worktree-state.js.map +1 -1
  165. package/package.json +2 -2
@@ -1,42 +1,54 @@
1
1
  // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
- // Pinned by: packages/daemon/src/verify/effect-reconciliation/stamp-withholds-recorded-targets.test.ts,
3
- // packages/daemon/src/verify/engine/verification-commit-sharing.test.ts,
2
+ // Pinned by: packages/daemon/src/integration/review-verdict-ruling-release.test.ts,
3
+ // packages/daemon/src/integration/shortfall-ruling-release.test.ts,
4
+ // packages/daemon/src/verify/effect-reconciliation/pending-injection-stamp.test.ts,
5
+ // packages/daemon/src/verify/effect-reconciliation/stamp-withholds-recorded-targets.test.ts,
4
6
  // packages/daemon/src/verify/engine/verification-engine.test.ts
5
7
  // PINNED-BY-END
6
8
  /**
7
- * The injection stamp is a POST-VERDICT side effect, never part of the verdict.
9
+ * The injection stamp is a POST-VERDICT side effect, never part of the verdict,
10
+ * and it is applied when the delivery is DONE.
8
11
  *
9
- * When a verify run passes a delivery anchored to an injection, the daemon
10
- * stamps that injection verified (the reality_tree_verify_injection compound op)
11
- * and surfaces any inward drift the reconciliation found. A stamp failure never
12
- * demotes the PASS: demoting it would discard a rendered deterministic verdict
13
- * and re-queue the whole suite on the same HEAD.
14
- *
15
- * The verdict is recorded as rendered, whatever happens here:
16
- * - the stamp is attempted once, in the run;
17
- * - on failure it is logged, surfaced ONCE as a machine-lane observation (not
18
- * as "no verdict"), and kept in a retry ledger;
19
- * - each verification tick re-attempts ONLY the ledgered stamps -- never the
20
- * suite -- with the same restatements and evidence the run authored, and
21
- * emits the drift once a stamp lands;
22
- * - a later verdict for the delivery supersedes its ledgered stamp: a newer
23
- * pass stamps afresh, and a non-pass means the stamp no longer describes the
24
- * delivery's work.
25
- * The ledger is in-process. After a restart (or once its attempts run out) the
26
- * stamp is still re-attempted by the durable safety nets, without the run's
27
- * restatements: the verify_linked_injection trigger on verify -> done
28
- * (guard/trigger-executor.ts) and the settle injection sweep
29
- * (completion/state-cascade/settle-injection-sweep.ts). So the tree does not stay unverified.
12
+ * A passing verify run authors the stamp of the injection its delivery is
13
+ * anchored to -- its restatements, the targets it withholds, its evidence -- but
14
+ * does not attempt it. The promotion gate verifies an injection only once every
15
+ * live delivery anchored to it is done (supabase/functions/_shared/injection-promotion-earned.ts),
16
+ * and verify judges a delivery while it is still in verify, ahead of its focus
17
+ * review. So:
18
+ * - a pass RECORDS its stamp as pending, durably (pending-injection-stamp.ts):
19
+ * nothing is attempted and nothing is filed;
20
+ * - each verification tick reads every pending stamp's delivery. In verify (or
21
+ * paused) the stamp waits, with no tick limit. Done: the stamp is applied with
22
+ * the run's restatements, and inward drift is emitted for what it flipped. Any
23
+ * other status (verify_failed, re-coding, cancelled, gone) means the verdict no
24
+ * longer describes the delivery's work: the stamp is dropped;
25
+ * - a later verdict for the delivery supersedes it: a newer pass records afresh,
26
+ * a non-pass drops it;
27
+ * - once done, a refusal because ANOTHER anchored delivery is not done keeps it
28
+ * pending, unreported. Any other failure is surfaced once as a machine-lane
29
+ * observation and retried, up to MAX_DONE_STAMP_FAILURES; after that the settle
30
+ * injection sweep stamps the injection from its declared futures;
31
+ * - the settle injection sweep (completion/state-cascade/settle-injection-sweep.ts)
32
+ * applies a pending stamp in place of its declared-future writeback
33
+ * (preferPendingStamp), so whichever reaches the injection first, it is judged
34
+ * once, with the run's restatements.
35
+ * A stamp never demotes the PASS: demoting it would discard a rendered verdict and
36
+ * re-queue the suite on the same HEAD.
30
37
  *
31
38
  * History: docs/daemon/history-verify.md (verify/effect-reconciliation/injection-stamp.ts).
32
39
  *
33
40
  * @module verify/effect-reconciliation/injection-stamp
34
41
  */
35
- import { ESCALATION_DISPOSITIONS, ESCALATION_REASONS } from '@telora/daemon-core';
42
+ import { DELIVERY_STATUS, ESCALATION_DISPOSITIONS, ESCALATION_REASONS } from '@telora/daemon-core';
43
+ import { isUnearnedPromotionRefusal } from '../../queries/verification/verification.js';
36
44
  import { createLogger } from '../../log/daemon-log.js';
37
45
  const log = createLogger({ module: 'verification' });
38
- /** Ticks a ledgered stamp is re-attempted before only the durable safety nets remain. */
39
- export const MAX_STAMP_RETRIES = 10;
46
+ /**
47
+ * Failed attempts on a DONE delivery's stamp before it is left to the settle
48
+ * sweep. Only a real failure counts: a refusal because another anchored
49
+ * delivery is not done is a wait, not a failure, and has no limit.
50
+ */
51
+ export const MAX_DONE_STAMP_FAILURES = 10;
40
52
  /**
41
53
  * Everything this stamp must NOT promote: the operator-EXCUSED shortfall nodes
42
54
  * PLUS the targets the focus's arm did not cover.
@@ -55,8 +67,8 @@ export const MAX_STAMP_RETRIES = 10;
55
67
  * explicitly costs one array and is the only signal that survives a read the
56
68
  * edge could not make.
57
69
  *
58
- * Carried on the ledgered stamp like every other field, so the retries re-send
59
- * exactly what the run authored rather than a set recomputed later.
70
+ * Carried on the pending stamp like every other field, so the stamp applied at
71
+ * done sends exactly what the run authored rather than a set recomputed later.
60
72
  *
61
73
  * `recordedTargetNodeIds` is null when NO reconciliation ran -- the run learned
62
74
  * nothing about coverage, so it withholds nothing on that account. Pure.
@@ -72,11 +84,9 @@ export function stampWithheldNodeIds(excusedNodeIds, recordedTargetNodeIds) {
72
84
  }
73
85
  return out;
74
86
  }
75
- /** Failed stamps awaiting a stamp-only retry, by delivery id. */
76
- const ledger = new Map();
77
87
  /** Attempt the stamp, then surface inward drift for what it flipped. Throws when the stamp does. */
78
- async function applyStamp(deps, v, stamp) {
79
- await deps.verifyInjection(v.injectionNodeId, stamp.restatements, stamp.evidence, stamp.withheldNodeIds);
88
+ async function applyStamp(deps, injectionNodeId, stamp) {
89
+ await deps.verifyInjection(injectionNodeId, stamp.restatements, stamp.evidence, stamp.withheldNodeIds);
80
90
  // INWARD drift (TEL-3/TEL-4): a target stamped legitimate_divergence is a tree
81
91
  // CLAIM reality contradicted -- surfaced only after the flip landed, carrying the
82
92
  // tree's ORIGINAL claim. Best-effort: a failure here must not undo the flip.
@@ -92,84 +102,146 @@ async function applyStamp(deps, v, stamp) {
92
102
  if (diverged.length === 0)
93
103
  return;
94
104
  try {
95
- await deps.emitInwardDrift(v.injectionNodeId, diverged, stamp.realityTreeId);
105
+ await deps.emitInwardDrift(injectionNodeId, diverged, stamp.realityTreeId);
96
106
  }
97
107
  catch (err) {
98
- log.warn(`[verification] inward drift emit failed for ${v.injectionNodeId}:`, err.message);
108
+ log.warn(`[verification] inward drift emit failed for ${injectionNodeId}:`, err.message);
99
109
  }
100
110
  }
101
- /** Surface a stamp failure once, in the machine lane: the verdict stands, only the stamp is owed. */
102
- async function surfaceStampFailure(deps, v, message) {
111
+ /** Surface a DONE delivery's stamp failure once, in the machine lane: the verdict stands, only the stamp is owed. */
112
+ async function surfaceStampFailure(deps, p, message) {
103
113
  try {
104
114
  await deps.fileEscalation({
105
115
  organizationId: deps.organizationId,
106
- ...(v.focusId ? { focusId: v.focusId } : {}),
107
- ...(v.productId ? { productId: v.productId } : {}),
108
- reason: `Verify passed delivery "${v.deliveryName}" but stamping its injection ${v.injectionNodeId} failed: ${message}. ` +
109
- 'The passed verdict is recorded; the daemon retries only the stamp on later verification ticks, and the ' +
110
- 'verify -> done trigger and settle injection sweep re-attempt it after that.',
116
+ ...(p.focusId ? { focusId: p.focusId } : {}),
117
+ ...(p.productId ? { productId: p.productId } : {}),
118
+ reason: `Delivery "${p.deliveryName}" passed verify and is done, but stamping its injection ${p.injectionNodeId} ` +
119
+ `failed: ${message}. The daemon retries only the stamp on later verification ticks, and the settle ` +
120
+ 'injection sweep stamps the injection after that.',
111
121
  reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
112
122
  disposition: ESCALATION_DISPOSITIONS.AGENT_RESOLVABLE,
113
123
  kind: 'verify_injection_stamp_failed',
114
- details: { delivery_id: v.deliveryId, injection_node_id: v.injectionNodeId, error: message },
124
+ details: { delivery_id: p.deliveryId, injection_node_id: p.injectionNodeId, error: message },
115
125
  });
116
126
  }
117
127
  catch (err) {
118
- log.warn(`[verification] could not surface the injection stamp failure for delivery ${v.deliveryId}:`, err.message);
128
+ log.warn(`[verification] could not surface the injection stamp failure for delivery ${p.deliveryId}:`, err.message);
119
129
  }
120
130
  }
121
131
  /**
122
- * Stamp the injection of a delivery whose verify PASSED. Never throws and never
123
- * touches the verdict: a failure is logged, surfaced once, and ledgered for a
124
- * stamp-only retry. Returns whether the stamp landed.
132
+ * Record the stamp of a delivery whose verify PASSED as pending until the
133
+ * delivery is done (module doc). Attempts nothing and files nothing; never
134
+ * throws and never touches the verdict. Returns whether the stamp was kept.
125
135
  */
126
- export async function stampPassedInjection(deps, v, stamp) {
136
+ export function recordPassedInjectionStamp(deps, v, stamp) {
137
+ const kept = deps.pendingStamps.write({
138
+ deliveryId: v.deliveryId,
139
+ deliveryName: v.deliveryName,
140
+ productId: v.productId,
141
+ focusId: v.focusId,
142
+ injectionNodeId: v.injectionNodeId,
143
+ restatements: stamp.restatements,
144
+ evidence: stamp.evidence,
145
+ withheldNodeIds: [...stamp.withheldNodeIds],
146
+ ...(stamp.realityTreeId !== undefined ? { realityTreeId: stamp.realityTreeId } : {}),
147
+ recordedAt: new Date().toISOString(),
148
+ failedAttempts: 0,
149
+ failureSurfaced: false,
150
+ });
151
+ if (kept) {
152
+ log.info(`[verification] delivery "${v.deliveryName}" (${v.deliveryId}) passed verify: its injection stamp ` +
153
+ `${v.injectionNodeId} is pending until the delivery is done`);
154
+ }
155
+ return kept;
156
+ }
157
+ /** A newly rendered verdict supersedes the delivery's pending stamp (module doc). */
158
+ export function supersedePendingStamp(deps, deliveryId, outcome) {
159
+ if (outcome !== 'pending')
160
+ deps.pendingStamps.drop(deliveryId);
161
+ }
162
+ /** Apply a DONE delivery's pending stamp: landed -> dropped; a sibling not done -> it waits; failed -> counted. */
163
+ async function applyDoneStamp(deps, p) {
127
164
  try {
128
- await applyStamp(deps, v, stamp);
129
- ledger.delete(v.deliveryId);
130
- return true;
165
+ await applyStamp(deps, p.injectionNodeId, p);
131
166
  }
132
167
  catch (err) {
168
+ if (isUnearnedPromotionRefusal(err)) {
169
+ log.debug(`[verification] injection stamp ${p.injectionNodeId} of done delivery ${p.deliveryId} waits: another delivery anchored to it is not done`);
170
+ return false;
171
+ }
133
172
  const message = err.message;
134
- const alreadyLedgered = ledger.has(v.deliveryId);
135
- ledger.set(v.deliveryId, { ...stamp, delivery: v, attempts: 0, lastError: message });
136
- log.warn(`[verification] post-verdict side effect failed for delivery "${v.deliveryName}" (${v.deliveryId}): ` +
137
- `injection stamp ${v.injectionNodeId}: ${message} -- the passed verdict stands; the stamp alone is retried`);
138
- if (!alreadyLedgered)
139
- await surfaceStampFailure(deps, v, message);
173
+ if (!p.failureSurfaced) {
174
+ log.warn(`[verification] post-verdict side effect failed for delivery "${p.deliveryName}" (${p.deliveryId}): ` +
175
+ `injection stamp ${p.injectionNodeId}: ${message} -- the passed verdict stands; the stamp alone is retried`);
176
+ await surfaceStampFailure(deps, p, message);
177
+ }
178
+ const failedAttempts = p.failedAttempts + 1;
179
+ if (failedAttempts >= MAX_DONE_STAMP_FAILURES) {
180
+ deps.pendingStamps.drop(p.deliveryId);
181
+ log.warn(`[verification] injection stamp ${p.injectionNodeId} for done delivery ${p.deliveryId} still failing after ` +
182
+ `${failedAttempts} attempts (${message}); left to the settle injection sweep`);
183
+ return false;
184
+ }
185
+ deps.pendingStamps.write({ ...p, failedAttempts, failureSurfaced: true });
186
+ log.debug(`[verification] injection stamp ${p.injectionNodeId} for done delivery ${p.deliveryId} failed again (${message}); retried next tick`);
140
187
  return false;
141
188
  }
189
+ deps.pendingStamps.drop(p.deliveryId);
190
+ log.info(`[verification] delivery "${p.deliveryName}" is done: injection ${p.injectionNodeId} stamped with the ` +
191
+ `${p.restatements.length} restatement(s) its passing verify authored`);
192
+ return true;
142
193
  }
143
- /** A newly recorded verdict supersedes the delivery's ledgered stamp (module doc). */
144
- export function supersedeLedgeredStamp(deliveryId, outcome) {
145
- if (outcome !== 'pending')
146
- ledger.delete(deliveryId);
147
- }
148
- /** Re-attempt ONLY the ledgered stamps -- no suite, no verdict. Called once per verification tick. */
149
- export async function retryLedgeredStamps(deps) {
150
- for (const [deliveryId, entry] of [...ledger]) {
194
+ /**
195
+ * Apply every pending stamp whose delivery is now done; drop the ones whose
196
+ * delivery left verify any other way. Called once per verification tick. Never
197
+ * throws: a delivery whose status cannot be read keeps its stamp for the next tick.
198
+ */
199
+ export async function applyPendingStamps(deps) {
200
+ const stampedThisTick = new Set();
201
+ for (const p of deps.pendingStamps.list()) {
202
+ let status;
151
203
  try {
152
- await applyStamp(deps, entry.delivery, entry);
153
- ledger.delete(deliveryId);
154
- log.info(`[verification] injection stamp ${entry.delivery.injectionNodeId} for delivery ${deliveryId} landed on retry`);
204
+ status = (await deps.readDeliveryGateRecord(p.deliveryId))?.executionStatus ?? null;
155
205
  }
156
206
  catch (err) {
157
- entry.attempts += 1;
158
- entry.lastError = err.message;
159
- if (entry.attempts < MAX_STAMP_RETRIES)
160
- continue;
161
- ledger.delete(deliveryId);
162
- log.warn(`[verification] injection stamp ${entry.delivery.injectionNodeId} for delivery ${deliveryId} still failing after ` +
163
- `${entry.attempts} retries (${entry.lastError}); left to the verify -> done trigger and the settle injection sweep`);
207
+ log.debug(`[verification] pending injection stamp of ${p.deliveryId} kept: its status could not be read (${err.message})`);
208
+ continue;
164
209
  }
210
+ if (status === DELIVERY_STATUS.VERIFY || status === DELIVERY_STATUS.PAUSED)
211
+ continue;
212
+ if (status !== DELIVERY_STATUS.DONE || stampedThisTick.has(p.injectionNodeId)) {
213
+ deps.pendingStamps.drop(p.deliveryId);
214
+ log.info(`[verification] pending injection stamp ${p.injectionNodeId} of delivery ${p.deliveryId} dropped: ` +
215
+ (status === DELIVERY_STATUS.DONE
216
+ ? 'a newer pending stamp for the same injection landed this tick'
217
+ : `the delivery is ${status ?? 'gone'}, so the passing verdict no longer describes its work`));
218
+ continue;
219
+ }
220
+ if (await applyDoneStamp(deps, p))
221
+ stampedThisTick.add(p.injectionNodeId);
165
222
  }
166
223
  }
167
- /** Test seam: the ledgered delivery ids. */
168
- export function __ledgeredStampsForTests() {
169
- return [...ledger.keys()];
170
- }
171
- /** Test seam: empty the ledger. */
172
- export function __resetStampLedgerForTests() {
173
- ledger.clear();
224
+ /**
225
+ * The settle sweep's per-injection verify, preferring a pending stamp: an
226
+ * injection a passing run left a stamp for is stamped with THAT stamp (the
227
+ * newest, when several anchored deliveries left one) and its pending stamps are
228
+ * dropped -- never with the sweep's writeback, which lands every target as a
229
+ * declared-future 'match' over the classifications the run authored. An
230
+ * injection with no pending stamp takes the writeback. A failed stamp throws,
231
+ * so the sweep records it and retries on its next settle.
232
+ */
233
+ export function preferPendingStamp(deps, writebackVerify) {
234
+ return async (injectionId, evidence) => {
235
+ const pending = deps.pendingStamps.list().filter((p) => p.injectionNodeId === injectionId);
236
+ const newest = pending[0];
237
+ if (!newest) {
238
+ await writebackVerify(injectionId, evidence);
239
+ return;
240
+ }
241
+ await applyStamp(deps, injectionId, newest);
242
+ for (const p of pending)
243
+ deps.pendingStamps.drop(p.deliveryId);
244
+ log.info(`[verification] settle sweep stamped injection ${injectionId} with the pending stamp of delivery ${newest.deliveryId}`);
245
+ };
174
246
  }
175
247
  //# sourceMappingURL=injection-stamp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"injection-stamp.js","sourceRoot":"","sources":["../../../src/verify/effect-reconciliation/injection-stamp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"injection-stamp.js","sourceRoot":"","sources":["../../../src/verify/effect-reconciliation/injection-stamp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { TargetRestatement } from './verify-restatement.js';
2
+ /** One passing run's stamp, waiting for its delivery to be done. */
3
+ export interface PendingInjectionStamp {
4
+ deliveryId: string;
5
+ deliveryName: string;
6
+ productId: string | null;
7
+ focusId: string | null;
8
+ injectionNodeId: string;
9
+ restatements: TargetRestatement[];
10
+ evidence: string;
11
+ /** Targets that must not flip with the injection (operator-excused, or recorded rather than judged). */
12
+ withheldNodeIds: string[];
13
+ realityTreeId?: string;
14
+ /** When the passing run recorded it. */
15
+ recordedAt: string;
16
+ /** Attempts after done that failed for a reason other than an unfinished sibling anchor. */
17
+ failedAttempts: number;
18
+ /** A failure after done is surfaced once; true once it was. */
19
+ failureSurfaced: boolean;
20
+ }
21
+ /** Where pending stamps are kept. Production: files under the state dir; tests: memory. */
22
+ export interface PendingStampStore {
23
+ /** Record (or replace) the delivery's pending stamp. False when it could not be kept. */
24
+ write(stamp: PendingInjectionStamp): boolean;
25
+ /** Every pending stamp, newest first. Empty when none can be read. */
26
+ list(): PendingInjectionStamp[];
27
+ /** Forget the delivery's pending stamp (absent is fine). */
28
+ drop(deliveryId: string): void;
29
+ }
30
+ /** Parse a stored stamp, or null when it is malformed (a malformed record applies nothing). */
31
+ export declare function parsePendingStamp(raw: unknown): PendingInjectionStamp | null;
32
+ /** The production store: one file per delivery under `dir` (default: the global state dir). */
33
+ export declare function filePendingStampStore(dir?: string): PendingStampStore;
34
+ /** An in-memory store (tests, and any caller with no state dir). */
35
+ export declare function memoryPendingStampStore(): PendingStampStore;
36
+ //# sourceMappingURL=pending-injection-stamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-injection-stamp.d.ts","sourceRoot":"","sources":["../../../src/verify/effect-reconciliation/pending-injection-stamp.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAKjE,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,wGAAwG;IACxG,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,2FAA2F;AAC3F,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC7C,sEAAsE;IACtE,IAAI,IAAI,qBAAqB,EAAE,CAAC;IAChC,4DAA4D;IAC5D,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAoBD,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,GAAG,IAAI,CAqB5E;AAcD,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAA0B,GAAG,iBAAiB,CAyCxF;AAED,oEAAoE;AACpE,wBAAgB,uBAAuB,IAAI,iBAAiB,CAc3D"}
@@ -0,0 +1,157 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/composition/settle-sweep-pending-stamp-wiring.test.ts,
3
+ // packages/daemon/src/integration/explicit-verdict-reuse.test.ts,
4
+ // packages/daemon/src/integration/review-verdict-ruling-release.test.ts,
5
+ // packages/daemon/src/integration/shortfall-ruling-release.test.ts,
6
+ // packages/daemon/src/verify/effect-reconciliation/pending-injection-stamp.test.ts,
7
+ // packages/daemon/src/verify/engine/verification-commit-sharing.test.ts
8
+ // PINNED-BY-END
9
+ /**
10
+ * The injection stamp a passing verify run authored, held durably until its
11
+ * delivery reaches done.
12
+ *
13
+ * The promotion gate verifies an injection only once every live delivery
14
+ * anchored to it is done (supabase/functions/_shared/injection-promotion-earned.ts),
15
+ * and verify judges a delivery while it is still in verify, ahead of its focus
16
+ * review. So the stamp a pass authors -- its restatements, the targets it
17
+ * withheld, its evidence -- is not attempted then: it is RECORDED here, and
18
+ * applied when the delivery is done (verify/effect-reconciliation/injection-stamp.ts).
19
+ *
20
+ * One file per delivery under the global state dir, written atomically (temp +
21
+ * rename) and REPLACED by a later pass of the same delivery. Host-local, like
22
+ * the review census (completion/review-exit/review-census-record.ts): the
23
+ * daemon that renders the verdict is the one that claims the product, polls its
24
+ * deliveries and runs its settle sweep, so the record is read where it is
25
+ * written, survives a daemon restart, and costs no schema change or edge
26
+ * release. A record that is missing, unreadable or malformed applies nothing:
27
+ * the settle sweep then stamps the injection from the tree's declared futures,
28
+ * which is what happened before this record existed.
29
+ *
30
+ * @module verify/effect-reconciliation/pending-injection-stamp
31
+ */
32
+ import { mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
33
+ import { resolve } from 'node:path';
34
+ import { resolveGlobalStateDir } from '../../daemon-state/daemon-process.js';
35
+ import { createLogger } from '../../log/daemon-log.js';
36
+ const log = createLogger({ module: 'verification' });
37
+ function isString(v) {
38
+ return typeof v === 'string';
39
+ }
40
+ function stringOrNull(v) {
41
+ if (v === null)
42
+ return null;
43
+ return isString(v) ? v : undefined;
44
+ }
45
+ function isRestatement(raw) {
46
+ if (typeof raw !== 'object' || raw === null)
47
+ return false;
48
+ const r = raw;
49
+ return isString(r.nodeId) && isString(r.statement)
50
+ && (r.classification === 'match' || r.classification === 'legitimate_divergence')
51
+ && (r.divergenceReason === undefined || isString(r.divergenceReason))
52
+ && isString(r.originalClaim);
53
+ }
54
+ /** Parse a stored stamp, or null when it is malformed (a malformed record applies nothing). */
55
+ export function parsePendingStamp(raw) {
56
+ if (typeof raw !== 'object' || raw === null)
57
+ return null;
58
+ const r = raw;
59
+ if (!isString(r.deliveryId) || !isString(r.deliveryName) || !isString(r.injectionNodeId))
60
+ return null;
61
+ if (!isString(r.evidence) || !isString(r.recordedAt))
62
+ return null;
63
+ const productId = stringOrNull(r.productId);
64
+ const focusId = stringOrNull(r.focusId);
65
+ if (productId === undefined || focusId === undefined)
66
+ return null;
67
+ const restatements = r.restatements;
68
+ const withheld = r.withheldNodeIds;
69
+ if (!Array.isArray(restatements) || !restatements.every(isRestatement))
70
+ return null;
71
+ if (!Array.isArray(withheld) || !withheld.every(isString))
72
+ return null;
73
+ if (r.realityTreeId !== undefined && !isString(r.realityTreeId))
74
+ return null;
75
+ return {
76
+ deliveryId: r.deliveryId, deliveryName: r.deliveryName, productId, focusId,
77
+ injectionNodeId: r.injectionNodeId, restatements, evidence: r.evidence,
78
+ withheldNodeIds: withheld, ...(isString(r.realityTreeId) ? { realityTreeId: r.realityTreeId } : {}),
79
+ recordedAt: r.recordedAt,
80
+ failedAttempts: typeof r.failedAttempts === 'number' && Number.isInteger(r.failedAttempts) ? r.failedAttempts : 0,
81
+ failureSurfaced: r.failureSurfaced === true,
82
+ };
83
+ }
84
+ function newestFirst(stamps) {
85
+ return stamps.sort((a, b) => Date.parse(b.recordedAt) - Date.parse(a.recordedAt));
86
+ }
87
+ function pendingStampDir() {
88
+ return resolve(resolveGlobalStateDir(), 'pending-injection-stamps');
89
+ }
90
+ function fileName(deliveryId) {
91
+ return `${deliveryId.replace(/[^a-zA-Z0-9._-]/g, '_')}.json`;
92
+ }
93
+ /** The production store: one file per delivery under `dir` (default: the global state dir). */
94
+ export function filePendingStampStore(dir = pendingStampDir()) {
95
+ return {
96
+ write(stamp) {
97
+ const path = resolve(dir, fileName(stamp.deliveryId));
98
+ const tmp = `${path}.${process.pid}.tmp`;
99
+ try {
100
+ mkdirSync(dir, { recursive: true });
101
+ writeFileSync(tmp, JSON.stringify(stamp, null, 2), { mode: 0o600 });
102
+ renameSync(tmp, path);
103
+ return true;
104
+ }
105
+ catch (err) {
106
+ log.warn(`[verification] could not record the pending injection stamp of delivery ${stamp.deliveryId}: ${err.message}`);
107
+ return false;
108
+ }
109
+ },
110
+ list() {
111
+ let names;
112
+ try {
113
+ names = readdirSync(dir).filter((name) => name.endsWith('.json'));
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ const stamps = [];
119
+ for (const name of names) {
120
+ try {
121
+ const parsed = parsePendingStamp(JSON.parse(readFileSync(resolve(dir, name), 'utf8')));
122
+ if (parsed)
123
+ stamps.push(parsed);
124
+ }
125
+ catch {
126
+ // Unreadable or malformed: applies nothing.
127
+ }
128
+ }
129
+ return newestFirst(stamps);
130
+ },
131
+ drop(deliveryId) {
132
+ try {
133
+ rmSync(resolve(dir, fileName(deliveryId)), { force: true });
134
+ }
135
+ catch (err) {
136
+ log.warn(`[verification] could not drop the pending injection stamp of delivery ${deliveryId}: ${err.message}`);
137
+ }
138
+ },
139
+ };
140
+ }
141
+ /** An in-memory store (tests, and any caller with no state dir). */
142
+ export function memoryPendingStampStore() {
143
+ const stamps = new Map();
144
+ return {
145
+ write(stamp) {
146
+ stamps.set(stamp.deliveryId, { ...stamp });
147
+ return true;
148
+ },
149
+ list() {
150
+ return newestFirst([...stamps.values()].map((s) => ({ ...s })));
151
+ },
152
+ drop(deliveryId) {
153
+ stamps.delete(deliveryId);
154
+ },
155
+ };
156
+ }
157
+ //# sourceMappingURL=pending-injection-stamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-injection-stamp.js","sourceRoot":"","sources":["../../../src/verify/effect-reconciliation/pending-injection-stamp.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
- // Pinned by: 26 tests -- run: npm run gen:pinned-by -- --list packages/daemon/src/verify/effect-reconciliation/verify-restatement.ts
2
+ // Pinned by: 27 tests -- run: npm run gen:pinned-by -- --list packages/daemon/src/verify/effect-reconciliation/verify-restatement.ts
3
3
  // PINNED-BY-END
4
4
  /**
5
5
  * Verify-time desired-effect reconciliation.
@@ -32,6 +32,7 @@ import type { AncestorLister } from '../gate-verdicts/judged-ancestor.js';
32
32
  import type { CommitVerdictPullRegistry } from '../run-selection/commit-verdict-pull.js';
33
33
  import type { InstallProbeTickDeps } from '../install-probe/install-probe-tick.js';
34
34
  import type { RecordedTargetsPersist } from '../effect-reconciliation/recorded-targets.js';
35
+ import type { PendingStampStore } from '../effect-reconciliation/pending-injection-stamp.js';
35
36
  import type { VerifyCheckout } from '../deterministic-gate/verification-checkout.js';
36
37
  import type { WorktreeProvisioningStatus } from '../../worktree/worktree-package-provisioning.js';
37
38
  import type { getPendingVerifications, PendingVerification, VerificationOutcome } from '../../queries/verification/verification.js';
@@ -91,6 +92,12 @@ export interface VerificationDeps {
91
92
  * operator EXCUSED (verify/shortfalls/shortfall-rulings.ts).
92
93
  */
93
94
  verifyInjection: (injectionNodeId: string, restatements?: TargetRestatement[], evidence?: string, withheldNodeIds?: readonly string[]) => Promise<void>;
95
+ /**
96
+ * Where a passing run's injection stamp waits for its delivery to be done
97
+ * (verify/effect-reconciliation/pending-injection-stamp.ts). Production: files
98
+ * under the global state dir, so a pending stamp survives a restart.
99
+ */
100
+ pendingStamps: PendingStampStore;
94
101
  /**
95
102
  * Read the operator shortfall rulings recorded on a delivery
96
103
  * (queries/verification/shortfall-rulings.ts). Applied to a judgement's shortfalls before
@@ -121,7 +128,9 @@ export interface VerificationDeps {
121
128
  * delivery whose commit set and rulings are unchanged is re-held from the
122
129
  * record instead of costing another model call
123
130
  * (verify/shortfalls/parked-shortfall-reuse.ts). A null record reads no park, and
124
- * the dispatch judges. Production reads the delivery row.
131
+ * the dispatch judges. The pending injection stamps read it each tick to
132
+ * apply a stamp once its delivery is done (injection-stamp.ts applyPendingStamps):
133
+ * null there means the delivery is gone. Production reads the delivery row.
125
134
  */
126
135
  readDeliveryGateRecord: (deliveryId: string) => Promise<DeliveryGateRecord | null>;
127
136
  /**