opencode-swarm 7.143.5 → 7.144.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.
- package/.opencode/skills/swarm-pr-review/SKILL.md +5 -5
- package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +129 -0
- package/dist/background/delegation-health.d.ts +213 -0
- package/dist/background/pending-delegations.d.ts +164 -16
- package/dist/background/pr-review-trigger-contract.d.ts +17 -0
- package/dist/cli/{config-doctor-y8wfw196.js → config-doctor-7gy47evn.js} +2 -2
- package/dist/cli/{core-zszmexgm.js → core-cpcspaw5.js} +1 -1
- package/dist/cli/{curator-llm-factory-xsg7wesn.js → curator-llm-factory-fyjmgxyp.js} +18 -18
- package/dist/cli/{curator-e2sp925h.js → curator-v97jnwn2.js} +18 -18
- package/dist/cli/{evidence-summary-service-pfppq7mv.js → evidence-summary-service-79mtxzhd.js} +6 -6
- package/dist/cli/{gate-evidence-23jnh3mb.js → gate-evidence-kgyqz1g1.js} +2 -2
- package/dist/cli/{guardrail-explain-byzmrgg1.js → guardrail-explain-9ry66z5g.js} +19 -19
- package/dist/cli/{guardrail-log-nr2g7hbw.js → guardrail-log-fe6smme1.js} +3 -3
- package/dist/cli/{hive-promoter-cw08380z.js → hive-promoter-vwq1dbh1.js} +18 -18
- package/dist/cli/{index-qdarzed6.js → index-0ck3e366.js} +1 -1
- package/dist/cli/{index-xmje20we.js → index-1pr8x10a.js} +2 -2
- package/dist/cli/{index-p844tcrm.js → index-269b52r3.js} +3 -3
- package/dist/cli/{index-04x9wx7d.js → index-3q9w6e6v.js} +1 -1
- package/dist/cli/{index-5866smj5.js → index-3v3dxf75.js} +3 -3
- package/dist/cli/{index-8aabbfhv.js → index-4fda8kkw.js} +1057 -92
- package/dist/cli/{index-jqxgdvr9.js → index-6p09gyra.js} +1 -1
- package/dist/cli/{index-mnj0ter5.js → index-8xertnqz.js} +3 -3
- package/dist/cli/{index-a1p87gew.js → index-d45d4zyq.js} +1 -1
- package/dist/cli/{index-y8r7z30j.js → index-d45yrzkg.js} +1 -1
- package/dist/cli/{index-1kr1vey5.js → index-e70d3xr7.js} +20 -20
- package/dist/cli/{index-a4dkd7m7.js → index-evvbmbbv.js} +1 -1
- package/dist/cli/{index-dg1v2gnh.js → index-ewzmjm7m.js} +1 -1
- package/dist/cli/{index-47z3jbxk.js → index-ez18gjk2.js} +3 -3
- package/dist/cli/{index-51axj9vd.js → index-j1scj25g.js} +481 -80
- package/dist/cli/{index-m7v7gggs.js → index-jqabjy7t.js} +4 -4
- package/dist/cli/{index-7en3eq3k.js → index-jvbfrwt2.js} +1 -1
- package/dist/cli/{index-tmc43mkc.js → index-mw6p3nt6.js} +1 -1
- package/dist/cli/{index-x64vt6sc.js → index-rd2082y4.js} +2 -2
- package/dist/cli/{index-q2nd6q9e.js → index-tfkfyshg.js} +1 -1
- package/dist/cli/{index-mbczeqs3.js → index-vb9cpaz4.js} +5 -5
- package/dist/cli/{index-at0h6cd6.js → index-zv4pwyas.js} +2 -2
- package/dist/cli/index.js +18 -18
- package/dist/cli/{knowledge-escalator-1g4p844a.js → knowledge-escalator-rmy3jcx4.js} +6 -6
- package/dist/cli/{knowledge-events-5699zzw0.js → knowledge-events-1tqpbwvj.js} +4 -4
- package/dist/cli/{knowledge-store-m5qjn5kd.js → knowledge-store-389ck792.js} +1 -1
- package/dist/cli/{knowledge-validator-xxnp8ear.js → knowledge-validator-kvtk6633.js} +2 -2
- package/dist/cli/{pending-delegations-b3pt3w5w.js → pending-delegations-thy8g30k.js} +27 -1
- package/dist/cli/{scan-cursor-qvky2yem.js → scan-cursor-ahgm4f5p.js} +2 -2
- package/dist/cli/{schema-wgb37f83.js → schema-epdq7ykx.js} +1 -1
- package/dist/cli/{scope-persistence-0wrb7ptt.js → scope-persistence-37s9n40v.js} +4 -4
- package/dist/cli/{skill-generator-khaw3jjw.js → skill-generator-4d2t5gem.js} +7 -7
- package/dist/cli/{worktree-collision-ownership-bfz3drxm.js → worktree-collision-ownership-j6d33p49.js} +1 -1
- package/dist/cli/{worktree-isolation-bv41gn3k.js → worktree-isolation-4628yaka.js} +18 -18
- package/dist/evaluation/contracts.d.ts +4 -4
- package/dist/evaluation/gate-ground-truth.d.ts +1 -1
- package/dist/hooks/init-orphan-recovery.d.ts +2 -0
- package/dist/hooks/pr-workflow-gate.d.ts +135 -1
- package/dist/index.js +446 -441
- package/dist/services/status-service.d.ts +9 -0
- package/dist/tools/complete-pr-workflow.d.ts +3 -1
- package/dist/tools/pr-workflow-status.d.ts +2 -2
- package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1135,7 +1135,7 @@ matched family owned exactly once across the dispatch, and every owned family
|
|
|
1135
1135
|
attested in that lane's output, or the lane fails for all of them. Include
|
|
1136
1136
|
the complete exact-set
|
|
1137
1137
|
`trigger_evaluation` ledger and the same exact current `pr_head_sha` in the
|
|
1138
|
-
initial micro dispatch, in a separate batch from base lanes. That first
|
|
1138
|
+
initial micro dispatch, in a separate batch from base lanes (those inline `trigger_evaluation` rows carry only `trigger_id`, `result`, and `evidence` — they must never include `source_batch_id` or `source_lane_id`, which belong only to `write_pr_review_trigger_eval`'s `rows`). That first
|
|
1139
1139
|
dispatch freezes the ledger for the session. A subsequent same-session micro
|
|
1140
1140
|
batch may omit `trigger_evaluation` and reuse the frozen ledger; when it
|
|
1141
1141
|
explicitly supplies a copy, the copy must remain exactly identical. The
|
|
@@ -1156,7 +1156,7 @@ plus provenance for every `MATCHED` row. The tool atomically writes
|
|
|
1156
1156
|
pass the exact reviewed merge-base as `base_sha`, the exact live base branch
|
|
1157
1157
|
tip/ref used to compute it as `base_ref`, and the same `pr_head_sha` to the
|
|
1158
1158
|
writer. The writer runs bounded `git merge-base -- <base_ref> <pr_head_sha>` and
|
|
1159
|
-
rejects any claimed `base_sha` that is not the exact result. It accepts only an
|
|
1159
|
+
rejects any claimed `base_sha` that is not the exact result. When that bounded re-check is unavailable (git timeout, spawn failure, unresolvable ref) but the supplied `base_ref` and `base_sha` exactly equal the durably bound review scope, the writer proceeds and discloses `base_verification: bound_fallback` on the receipt, which synthesis must surface in the final review report (`references/lane-output-recoverability.md`); every other outcome stays fail-closed. It accepts only an
|
|
1160
1160
|
exact eleven-row v2 receipt backed by verifiable provenance (identity, ownership, digest, retained artifact); a coverage-QUALITY failure is disclosed on the receipt as `coverage_degradations` and the run proceeds, with synthesis disclosing degraded families (`references/lane-output-recoverability.md`). `NOT_TRIGGERED` rows are provenance-free. Counts are recomputed and
|
|
1161
1161
|
must agree. It never uses keyword or path classification alone as absence
|
|
1162
1162
|
evidence. Any head mismatch makes persistence fail. Historical unversioned and
|
|
@@ -1946,9 +1946,9 @@ are:
|
|
|
1946
1946
|
`pr_head_sha`, `base_sha`, and `base_ref`.
|
|
1947
1947
|
2. **Call `abort_pr_workflow`** with `mode: "PR_REVIEW"`, `kind: "recovery"`,
|
|
1948
1948
|
and a one-line `reason` describing the blocker. The tool clears the durable gate state
|
|
1949
|
-
and stops the auto-resume loop. It refuses while PR workflow lanes are
|
|
1950
|
-
|
|
1951
|
-
|
|
1949
|
+
and stops the auto-resume loop. It refuses only while PR workflow lanes are still LIVE (a recent `updatedAt`); collect those with `collect_lane_results` first.
|
|
1950
|
+
Lanes idle past the 30-minute staleness horizon settle as presumed-stale instead of blocking, disclosed as `presumed_stale_lanes` on the response and in `.swarm/events.jsonl`; a schema-invalid (but JSON-parseable) gate state no longer defeats abort either. See `references/lane-output-recoverability.md`.
|
|
1951
|
+
It accepts both unbound and bound PR_REVIEW workflows so exhausted
|
|
1952
1952
|
post-bind discovery or validation cannot strand the gate. An audit event is
|
|
1953
1953
|
appended to `.swarm/events.jsonl`.
|
|
1954
1954
|
When the tool reports `checkout_restore_required`, immediately call
|
|
@@ -52,3 +52,132 @@ synthesis phase MUST disclose every degraded family, with its recorded reason,
|
|
|
52
52
|
in the final review report. Retries remain the first resort (COVERAGE GATE); a
|
|
53
53
|
missing provenance chain still fails closed, and the reviewer/critic inventory
|
|
54
54
|
skips exactly the receipt-disclosed dispatch tuples.
|
|
55
|
+
|
|
56
|
+
## Bounded merge-base fallback (`base_verification`)
|
|
57
|
+
|
|
58
|
+
Every v2 receipt now records how its `base_sha` was verified at write time:
|
|
59
|
+
|
|
60
|
+
- **`live`** — the writer re-derived the merge base with a bounded
|
|
61
|
+
`git merge-base -- <base_ref> <pr_head_sha>` and it matched the supplied
|
|
62
|
+
`base_sha` exactly. This is the normal path.
|
|
63
|
+
- **`bound_fallback`** — that re-derivation was **unavailable**, and the writer
|
|
64
|
+
proceeded because the supplied `base_ref`/`base_sha` exactly equalled the
|
|
65
|
+
review scope already bound durably at dispatch time.
|
|
66
|
+
|
|
67
|
+
The distinction matters because the git helper collapses every failure mode
|
|
68
|
+
into a bare `null`: a timed-out git call, a git process that failed to spawn, a
|
|
69
|
+
`base_ref` that is unresolvable in this checkout, and a ref rejected as an
|
|
70
|
+
unsafe revision token are indistinguishable to the caller. Treating that `null`
|
|
71
|
+
as *refutation* rather than *unavailability* made review completion permanently
|
|
72
|
+
unsatisfiable — every retry re-failed identically, the trigger-eval receipt was
|
|
73
|
+
never written, an omission dispatch could not repair it, and the only exit was
|
|
74
|
+
`abort_pr_workflow`. The bound scope is not a weaker fact: it was itself derived
|
|
75
|
+
by a real `git merge-base` at dispatch and only trimmed/lowercased on the way
|
|
76
|
+
into durable state, so re-deriving it at write time is a redundant re-check.
|
|
77
|
+
|
|
78
|
+
What `bound_fallback` does and does not mean:
|
|
79
|
+
|
|
80
|
+
- It does **not** widen what was reviewed. The reviewed range stays SHA-scoped
|
|
81
|
+
(`base_sha...pr_head_sha`), identical to the `live` path.
|
|
82
|
+
- It does mean post-bind movement or deletion of the base ref would go
|
|
83
|
+
undetected for this run — the one staleness signal the live re-check provides.
|
|
84
|
+
- It never relaxes a mismatch. If the re-check is unavailable **and** the
|
|
85
|
+
supplied scope differs from the bound scope in either half, the writer fails
|
|
86
|
+
closed with an enriched message naming the possible causes and the recovery
|
|
87
|
+
options. If the gate has no bound base at all, the writer fails closed before
|
|
88
|
+
attempting resolution.
|
|
89
|
+
|
|
90
|
+
**Synthesis obligation (skill-directed):** when the trigger-eval result or the persisted receipt
|
|
91
|
+
reports `base_verification: bound_fallback`, the final review report MUST
|
|
92
|
+
disclose it. State that the merge base could not be re-verified live at write time and that the review was
|
|
93
|
+
scoped to the durably bound base. Do not silently present the review as if the
|
|
94
|
+
base had been re-verified. (Unlike `coverage_degradations`, which the workflow gate reads as a machine-enforced waiver filter, `bound_fallback` disclosure is skill-directed.)
|
|
95
|
+
|
|
96
|
+
## Provenance fields: dispatch ledger vs. writer rows
|
|
97
|
+
|
|
98
|
+
Two different row shapes carry the trigger evaluation, and mixing them up is a
|
|
99
|
+
recurring source of first-dispatch failures:
|
|
100
|
+
|
|
101
|
+
- **Dispatch-time `trigger_evaluation` rows** (the inline ledger frozen by the
|
|
102
|
+
first micro dispatch) use the strict inline schema: `trigger_id`, `result`,
|
|
103
|
+
and `evidence`, and nothing else. Adding `source_batch_id` or
|
|
104
|
+
`source_lane_id` there is rejected — at dispatch time no lane has run yet, so
|
|
105
|
+
there is no provenance to cite, and the frozen-ledger digest is computed over
|
|
106
|
+
exactly those three fields.
|
|
107
|
+
- **Writer `rows`** (passed to `write_pr_review_trigger_eval` after the lanes
|
|
108
|
+
settle) carry the provenance: every `MATCHED` row adds the `source_batch_id`
|
|
109
|
+
and `source_lane_id` returned by its completed micro lane, and every
|
|
110
|
+
`NOT_TRIGGERED` row must omit both.
|
|
111
|
+
|
|
112
|
+
Classifications must be identical across the two — the writer rejects
|
|
113
|
+
classification drift from the frozen ledger — while `evidence` may be reworded
|
|
114
|
+
in the writer call and is simply ignored (the frozen values are authoritative).
|
|
115
|
+
|
|
116
|
+
## Gate-level recovery: stuck lanes, corrupted state, amended inventory
|
|
117
|
+
|
|
118
|
+
Three wedge states used to leave a workflow with no exit through any tool. Each
|
|
119
|
+
now degrades with disclosure; the contradiction cases still fail closed.
|
|
120
|
+
|
|
121
|
+
### Stale lanes no longer block abort or completion
|
|
122
|
+
|
|
123
|
+
A lane whose background process dies without writing a terminal snapshot used to
|
|
124
|
+
count as "in flight" forever, and the same predicate gates `abort_pr_workflow`,
|
|
125
|
+
the PR_REVIEW to PR_FEEDBACK transition, and `complete_pr_workflow` — so the
|
|
126
|
+
escape hatch was refused by the very condition it exists to resolve.
|
|
127
|
+
|
|
128
|
+
A lane whose delegation record has not advanced its `updatedAt` for 30 minutes is
|
|
129
|
+
now **presumed stale** and settles instead of blocking. The disclosure appears as
|
|
130
|
+
`presumed_stale_lanes` / `presumed_stale_disclosure` on the `abort_pr_workflow`
|
|
131
|
+
and `complete_pr_workflow` responses, as a `pr_workflow_lanes_presumed_stale`
|
|
132
|
+
record in `.swarm/events.jsonl`, and on the `pr_workflow_aborted` audit event.
|
|
133
|
+
The delegation record itself is transitioned to `stale`.
|
|
134
|
+
|
|
135
|
+
A lane with a **recent** `updatedAt` still blocks — a check that can run and
|
|
136
|
+
reports "still progressing" is not softened. Collect it with
|
|
137
|
+
`collect_lane_results`, or wait for the horizon.
|
|
138
|
+
|
|
139
|
+
### A corrupted gate state no longer defeats abort
|
|
140
|
+
|
|
141
|
+
If the durable gate-state file fails schema validation but is still valid JSON,
|
|
142
|
+
`abort_pr_workflow` and `pr_workflow_status` read it through a **recovery-only**
|
|
143
|
+
reader that salvages `sessionID`, `mode`, `prHeadSha`, and — when each is
|
|
144
|
+
individually well-formed — `revision`, `prFeedbackReadyToPublish` and
|
|
145
|
+
`checkoutRecovery`. Every other reader, including all write and completion paths,
|
|
146
|
+
still refuses the file, so a salvaged view can never be acted on as if it were
|
|
147
|
+
valid. `stateSalvaged` / `stateSalvageDisclosure` name the schema errors.
|
|
148
|
+
|
|
149
|
+
Boundaries that deliberately did NOT soften:
|
|
150
|
+
|
|
151
|
+
- **Unparseable bytes fail everywhere.** There is nothing to salvage.
|
|
152
|
+
- **Unreadable identity fails everywhere.** Without a readable `sessionID` and
|
|
153
|
+
`mode` there is no provable subject to act on.
|
|
154
|
+
- **An unreadable `prFeedbackReadyToPublish` is treated as ARMED**, so abort
|
|
155
|
+
still refuses. Corrupting that one record must never become a way past the
|
|
156
|
+
armed-abort refusal.
|
|
157
|
+
- When `revision` cannot be salvaged, abort takes the documented
|
|
158
|
+
compare-and-swap escape and says so:
|
|
159
|
+
`state revision unsalvageable; cleared without compare-and-swap`.
|
|
160
|
+
|
|
161
|
+
### The PR_FEEDBACK inventory is append-only, not immutable
|
|
162
|
+
|
|
163
|
+
A finding discovered after `declarePrFeedbackInventory` used to require
|
|
164
|
+
`abort_pr_workflow` plus a full restart, discarding completed verification work
|
|
165
|
+
for correctly-declared items. Re-declaring with **additional** items is now
|
|
166
|
+
accepted; every previously-declared entry must still be present, so mutation and
|
|
167
|
+
removal still hard-fail (`inventory is append-only after declaration`).
|
|
168
|
+
|
|
169
|
+
What an amendment costs, and what it preserves:
|
|
170
|
+
|
|
171
|
+
- Completed **verification** batches for the original items are preserved. Cover
|
|
172
|
+
the appended item with a new verification batch owning just that item.
|
|
173
|
+
- Stage A must be re-recorded over the full amended inventory, and each ordered
|
|
174
|
+
gate phase must be re-run with a lane owning every current inventory item —
|
|
175
|
+
a gate batch recorded before the amendment no longer settles its phase. This
|
|
176
|
+
is deliberate: it is the control that stops an appended item reaching
|
|
177
|
+
publication with no verdict.
|
|
178
|
+
- Publication is disarmed by an amendment (the armed record attested coverage of
|
|
179
|
+
the pre-amendment inventory). Re-arm with one `complete_pr_workflow` call.
|
|
180
|
+
- Every appended entry is recorded in an audit ledger surfaced as
|
|
181
|
+
`inventory_amendments` on the completion response and `inventoryAmendments` on
|
|
182
|
+
`pr_workflow_status`. The ledger is bounded at 128 entries and is never pruned;
|
|
183
|
+
further amendments are refused at the cap.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable health/status artifact for the background-delegation store (issue #2034,
|
|
3
|
+
* parent #1659).
|
|
4
|
+
*
|
|
5
|
+
* This module owns ONLY the `.swarm/background-delegations-health.json` artifact:
|
|
6
|
+
* a bounded, machine-readable observation copy of ledger health (bytes/limit/
|
|
7
|
+
* pressure, last successful checkpoint, recovery source, the most recent durable
|
|
8
|
+
* uncertainty, and live-set counters). It deliberately imports nothing from the
|
|
9
|
+
* store itself so `pending-delegations.ts` can write the artifact while holding
|
|
10
|
+
* the store lock without an import cycle, and so `/swarm status` can read it with
|
|
11
|
+
* nothing more than `statSync` + one small JSON read — never a ledger fold.
|
|
12
|
+
*
|
|
13
|
+
* The artifact is an OBSERVATION copy, never an ownership or settlement record
|
|
14
|
+
* (issue requirement 8): deleting it loses no state, only visibility. Counters
|
|
15
|
+
* are computed and refreshed by the store (at compaction time, under the store
|
|
16
|
+
* lock) and by recovery observations; readers treat a missing artifact as
|
|
17
|
+
* "nothing to report" rather than "healthy".
|
|
18
|
+
*/
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
export declare const BACKGROUND_DELEGATIONS_HEALTH_FILE = "background-delegations-health.json";
|
|
21
|
+
/**
|
|
22
|
+
* Strict recovery bound for the delegation ledger/tail (issue #2034: the
|
|
23
|
+
* guard itself is unchanged — compaction exists so normal operation never
|
|
24
|
+
* approaches it). Lives here so the health module can default a valid artifact
|
|
25
|
+
* without importing the store (no import cycle).
|
|
26
|
+
*/
|
|
27
|
+
export declare const MAX_RECOVERY_LEDGER_BYTES: number;
|
|
28
|
+
export type DelegationLedgerPressureBand = 'ok' | 'nominal' | 'compact-overdue' | 'fail-closed';
|
|
29
|
+
export interface DelegationCheckpointAuditSummary {
|
|
30
|
+
dispatchCount: number;
|
|
31
|
+
terminalsByStatus: {
|
|
32
|
+
completed: number;
|
|
33
|
+
error: number;
|
|
34
|
+
cancelled: number;
|
|
35
|
+
stale: number;
|
|
36
|
+
};
|
|
37
|
+
settledCount: number;
|
|
38
|
+
preservedCount: number;
|
|
39
|
+
lateTerminalCount: number;
|
|
40
|
+
compactedTransitionCount: number;
|
|
41
|
+
compactedRecordCount: number;
|
|
42
|
+
firstDispatchAt: number | null;
|
|
43
|
+
lastTerminalAt: number | null;
|
|
44
|
+
lastCompactionAt: number;
|
|
45
|
+
}
|
|
46
|
+
export interface DelegationHealthCheckpointSection {
|
|
47
|
+
sequence: number;
|
|
48
|
+
createdAt: number;
|
|
49
|
+
liveRecords: number;
|
|
50
|
+
closedSummaries: number;
|
|
51
|
+
bytes: number;
|
|
52
|
+
audit: DelegationCheckpointAuditSummary;
|
|
53
|
+
}
|
|
54
|
+
export interface DelegationHealthRecoverySection {
|
|
55
|
+
source: 'checkpoint+tail' | 'checkpoint+ledger-suffix' | 'legacy-ledger' | 'unknown';
|
|
56
|
+
at: number;
|
|
57
|
+
ok: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
repairHint?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface DelegationHealthUncertaintySection {
|
|
62
|
+
reason: string;
|
|
63
|
+
at: number;
|
|
64
|
+
source: string;
|
|
65
|
+
repairHint?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface DelegationLedgerHealth {
|
|
68
|
+
schemaVersion: 1;
|
|
69
|
+
updatedAt: number;
|
|
70
|
+
ledger: {
|
|
71
|
+
bytes: number;
|
|
72
|
+
limitBytes: number;
|
|
73
|
+
pressurePct: number;
|
|
74
|
+
band: DelegationLedgerPressureBand;
|
|
75
|
+
};
|
|
76
|
+
checkpoint: DelegationHealthCheckpointSection | null;
|
|
77
|
+
recovery: DelegationHealthRecoverySection | null;
|
|
78
|
+
lastUncertainty: DelegationHealthUncertaintySection | null;
|
|
79
|
+
counts: {
|
|
80
|
+
activeOwners: number;
|
|
81
|
+
pendingAdvisories: number;
|
|
82
|
+
lateTerminals: number;
|
|
83
|
+
orphanWorktreeOwners: number;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export declare const DelegationCheckpointAuditSchema: z.ZodObject<{
|
|
87
|
+
dispatchCount: z.ZodNumber;
|
|
88
|
+
terminalsByStatus: z.ZodObject<{
|
|
89
|
+
completed: z.ZodNumber;
|
|
90
|
+
error: z.ZodNumber;
|
|
91
|
+
cancelled: z.ZodNumber;
|
|
92
|
+
stale: z.ZodNumber;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
settledCount: z.ZodNumber;
|
|
95
|
+
preservedCount: z.ZodNumber;
|
|
96
|
+
lateTerminalCount: z.ZodNumber;
|
|
97
|
+
compactedTransitionCount: z.ZodNumber;
|
|
98
|
+
compactedRecordCount: z.ZodNumber;
|
|
99
|
+
firstDispatchAt: z.ZodNullable<z.ZodNumber>;
|
|
100
|
+
lastTerminalAt: z.ZodNullable<z.ZodNumber>;
|
|
101
|
+
lastCompactionAt: z.ZodNumber;
|
|
102
|
+
}, z.core.$strict>;
|
|
103
|
+
export declare const DelegationLedgerHealthSchema: z.ZodObject<{
|
|
104
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
105
|
+
updatedAt: z.ZodNumber;
|
|
106
|
+
ledger: z.ZodObject<{
|
|
107
|
+
bytes: z.ZodNumber;
|
|
108
|
+
limitBytes: z.ZodNumber;
|
|
109
|
+
pressurePct: z.ZodNumber;
|
|
110
|
+
band: z.ZodEnum<{
|
|
111
|
+
ok: "ok";
|
|
112
|
+
nominal: "nominal";
|
|
113
|
+
"compact-overdue": "compact-overdue";
|
|
114
|
+
"fail-closed": "fail-closed";
|
|
115
|
+
}>;
|
|
116
|
+
}, z.core.$strict>;
|
|
117
|
+
checkpoint: z.ZodNullable<z.ZodObject<{
|
|
118
|
+
sequence: z.ZodNumber;
|
|
119
|
+
createdAt: z.ZodNumber;
|
|
120
|
+
liveRecords: z.ZodNumber;
|
|
121
|
+
closedSummaries: z.ZodNumber;
|
|
122
|
+
bytes: z.ZodNumber;
|
|
123
|
+
audit: z.ZodObject<{
|
|
124
|
+
dispatchCount: z.ZodNumber;
|
|
125
|
+
terminalsByStatus: z.ZodObject<{
|
|
126
|
+
completed: z.ZodNumber;
|
|
127
|
+
error: z.ZodNumber;
|
|
128
|
+
cancelled: z.ZodNumber;
|
|
129
|
+
stale: z.ZodNumber;
|
|
130
|
+
}, z.core.$strict>;
|
|
131
|
+
settledCount: z.ZodNumber;
|
|
132
|
+
preservedCount: z.ZodNumber;
|
|
133
|
+
lateTerminalCount: z.ZodNumber;
|
|
134
|
+
compactedTransitionCount: z.ZodNumber;
|
|
135
|
+
compactedRecordCount: z.ZodNumber;
|
|
136
|
+
firstDispatchAt: z.ZodNullable<z.ZodNumber>;
|
|
137
|
+
lastTerminalAt: z.ZodNullable<z.ZodNumber>;
|
|
138
|
+
lastCompactionAt: z.ZodNumber;
|
|
139
|
+
}, z.core.$strict>;
|
|
140
|
+
}, z.core.$strict>>;
|
|
141
|
+
recovery: z.ZodNullable<z.ZodObject<{
|
|
142
|
+
source: z.ZodEnum<{
|
|
143
|
+
unknown: "unknown";
|
|
144
|
+
"checkpoint+tail": "checkpoint+tail";
|
|
145
|
+
"checkpoint+ledger-suffix": "checkpoint+ledger-suffix";
|
|
146
|
+
"legacy-ledger": "legacy-ledger";
|
|
147
|
+
}>;
|
|
148
|
+
at: z.ZodNumber;
|
|
149
|
+
ok: z.ZodBoolean;
|
|
150
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
151
|
+
repairHint: z.ZodOptional<z.ZodString>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
153
|
+
lastUncertainty: z.ZodNullable<z.ZodObject<{
|
|
154
|
+
reason: z.ZodString;
|
|
155
|
+
at: z.ZodNumber;
|
|
156
|
+
source: z.ZodString;
|
|
157
|
+
repairHint: z.ZodOptional<z.ZodString>;
|
|
158
|
+
}, z.core.$strict>>;
|
|
159
|
+
counts: z.ZodObject<{
|
|
160
|
+
activeOwners: z.ZodNumber;
|
|
161
|
+
pendingAdvisories: z.ZodNumber;
|
|
162
|
+
lateTerminals: z.ZodNumber;
|
|
163
|
+
orphanWorktreeOwners: z.ZodNumber;
|
|
164
|
+
}, z.core.$strict>;
|
|
165
|
+
}, z.core.$strict>;
|
|
166
|
+
/**
|
|
167
|
+
* Test seam for the atomic-rename retry (issue #2034): tests inject a
|
|
168
|
+
* transient EPERM here to exercise the real retry loop.
|
|
169
|
+
*/
|
|
170
|
+
export declare const _healthInternals: {
|
|
171
|
+
renameOnce: (from: string, to: string) => void;
|
|
172
|
+
};
|
|
173
|
+
export declare function healthArtifactPath(directory: string): string;
|
|
174
|
+
/** Read the health artifact; null when absent or malformed (readers fail open). */
|
|
175
|
+
export declare function readDelegationHealthArtifact(directory: string): DelegationLedgerHealth | null;
|
|
176
|
+
/**
|
|
177
|
+
* Merge a partial update into the current artifact and write it atomically.
|
|
178
|
+
* Callers that can hold the store lock must do so (compaction, recovery
|
|
179
|
+
* observation); standalone readers never write. Merge is section-wise: a null
|
|
180
|
+
* section clears it, an undefined section preserves the existing value.
|
|
181
|
+
*/
|
|
182
|
+
export declare function writeDelegationHealthArtifact(directory: string, update: {
|
|
183
|
+
ledger?: DelegationLedgerHealth['ledger'];
|
|
184
|
+
checkpoint?: DelegationLedgerHealth['checkpoint'] | null;
|
|
185
|
+
recovery?: DelegationLedgerHealth['recovery'] | null;
|
|
186
|
+
lastUncertainty?: DelegationLedgerHealth['lastUncertainty'] | null;
|
|
187
|
+
counts?: DelegationLedgerHealth['counts'];
|
|
188
|
+
uncertainty?: DelegationHealthUncertaintySection;
|
|
189
|
+
}): DelegationLedgerHealth | null;
|
|
190
|
+
/**
|
|
191
|
+
* Record a startup-recovery observation (called by init-orphan-recovery after
|
|
192
|
+
* its scans): how the primary store was reconstructed and whether it succeeded.
|
|
193
|
+
* A failing observation also becomes the durable `lastUncertainty`, so the
|
|
194
|
+
* incident stays visible in `/swarm status` after the in-memory failure is gone
|
|
195
|
+
* (issue #1659). Best-effort: never throws.
|
|
196
|
+
*/
|
|
197
|
+
export declare function recordDelegationRecoveryObservation(directory: string, observation: {
|
|
198
|
+
source: 'checkpoint+tail' | 'checkpoint+ledger-suffix' | 'legacy-ledger' | 'unknown';
|
|
199
|
+
ok: boolean;
|
|
200
|
+
reason?: string;
|
|
201
|
+
repairHint?: string;
|
|
202
|
+
}): void;
|
|
203
|
+
/**
|
|
204
|
+
* Fold-free health collection for `/swarm status`: statSync of the ledger and
|
|
205
|
+
* checkpoint, a display-tolerant manifest peek (sequence/tailRolled only), and
|
|
206
|
+
* the durable artifact. Never reads or folds the ledger contents, so the status
|
|
207
|
+
* path stays bounded no matter how much history exists (issue #2034 critic #5).
|
|
208
|
+
*/
|
|
209
|
+
export declare function collectDelegationLedgerHealth(directory: string, options: {
|
|
210
|
+
ledgerLimitBytes: number;
|
|
211
|
+
lowWaterBytes: number;
|
|
212
|
+
highWaterBytes: number;
|
|
213
|
+
}): DelegationLedgerHealth | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Durable pending background-delegation store (issue #1151, PR 2 Stage A
|
|
2
|
+
* Durable pending background-delegation store (issue #1151, PR 2 Stage A;
|
|
3
|
+
* bounded recovery via checkpoint/tail compaction — issue #2034).
|
|
3
4
|
*
|
|
4
5
|
* Append-only JSONL event log under project-root `.swarm/background-delegations.jsonl`.
|
|
5
6
|
* Each line is a full record snapshot; readers fold to the latest snapshot per
|
|
@@ -7,38 +8,116 @@
|
|
|
7
8
|
* async advisory lanes so trusted completions can be correlated to a real dispatch.
|
|
8
9
|
* The stale sweep bounds the number of permanently-running entries by transitioning
|
|
9
10
|
* them to `stale`, so the folded in-memory view stays bounded by distinct correlationIds.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
|
+
* Bounded recovery (issue #2034): the raw log alone is no longer the recovery
|
|
13
|
+
* source once history grows. Compaction — run lazily under the store lock when the
|
|
14
|
+
* ledger passes `DELEGATION_COMPACTION_HIGH_WATER_BYTES` — checkpoints the folded
|
|
15
|
+
* authoritative state (active ownership, terminal results, coder settlement, pending
|
|
16
|
+
* advisory inbox) plus compact closed-record summaries into
|
|
17
|
+
* `.swarm/background-delegations.checkpoint.json`, publishes it via
|
|
18
|
+
* `.swarm/background-delegations.manifest.json`, and rolls the ledger to the
|
|
19
|
+
* post-cut transition tail. Recovery folds checkpoint + bounded tail with hard
|
|
20
|
+
* byte/count bounds and preserves fail-closed uncertainty; the 4 MiB
|
|
21
|
+
* `MAX_RECOVERY_LEDGER_BYTES` guard is unchanged and still applies to legacy
|
|
22
|
+
* uncheckpointed ledgers.
|
|
12
23
|
*
|
|
13
24
|
* Scope: dispatch records `pending`/`running` snapshots, collection or trusted synthetic
|
|
14
25
|
* completions record terminal snapshots, and the stale sweep records `stale` snapshots.
|
|
15
26
|
* This store itself has no gate-advancement side effect. Stage B gate ingestion is a
|
|
16
|
-
* separate consumer of trusted terminal snapshots.
|
|
27
|
+
* separate consumer of trusted terminal snapshots. Circuit-breaker and transient-retry
|
|
28
|
+
* counters are invocation-owned and are NEVER serialized here (issue #2034 req 9).
|
|
17
29
|
*
|
|
18
|
-
* Concurrency: all writes (append, sweep) run under a single
|
|
19
|
-
* `withEvidenceLock`, so concurrent dispatches/sweeps cannot
|
|
20
|
-
* lock-free (line-oriented; partial trailing lines are
|
|
30
|
+
* Concurrency: all writes (append, sweep, compaction) run under a single
|
|
31
|
+
* project-scoped lock via `withEvidenceLock`, so concurrent dispatches/sweeps cannot
|
|
32
|
+
* interleave appends. Reads are lock-free (line-oriented; partial trailing lines are
|
|
33
|
+
* skipped defensively by the lenient reader; the strict recovery reader fails closed).
|
|
21
34
|
*
|
|
22
|
-
* Containment:
|
|
23
|
-
* `.swarm/` (Invariant 4).
|
|
35
|
+
* Containment: every path is validated with `validateSwarmPath`, so it can never
|
|
36
|
+
* escape `.swarm/` (Invariant 4).
|
|
24
37
|
*/
|
|
38
|
+
import { type DelegationCheckpointAuditSummary } from './delegation-health.js';
|
|
25
39
|
export declare const BACKGROUND_DELEGATIONS_FILE = "background-delegations.jsonl";
|
|
26
40
|
export declare const BACKGROUND_DELEGATION_FALLBACK_DIR = "background-delegation-fallback";
|
|
27
41
|
export declare const BACKGROUND_CODER_RESERVATIONS_FILE = "background-coder-reservations.json";
|
|
42
|
+
export declare const BACKGROUND_DELEGATIONS_CHECKPOINT_FILE = "background-delegations.checkpoint.json";
|
|
43
|
+
export declare const BACKGROUND_DELEGATIONS_MANIFEST_FILE = "background-delegations.manifest.json";
|
|
28
44
|
export declare const MAX_LIVE_BACKGROUND_FALLBACKS = 256;
|
|
29
45
|
export declare const MAX_LIVE_BACKGROUND_CODER_RESERVATIONS = 256;
|
|
30
46
|
export declare const MAX_BACKGROUND_OBSERVED_FILES = 5000;
|
|
31
47
|
export declare const MAX_BACKGROUND_ADVISORY_CHARS = 4000;
|
|
48
|
+
/** Strict recovery bound for the ledger/tail (issue #2034: unchanged guard). */
|
|
49
|
+
export { MAX_RECOVERY_LEDGER_BYTES } from './delegation-health.js';
|
|
50
|
+
/**
|
|
51
|
+
* Compaction watermarks (issue #2034). Auto-compaction fires above the high
|
|
52
|
+
* water mark so the post-roll tail plus one in-flight append (~250 KiB worst
|
|
53
|
+
* case) stays far below the 4 MiB strict recovery bound in normal operation.
|
|
54
|
+
*/
|
|
55
|
+
export declare const DELEGATION_COMPACTION_LOW_WATER_BYTES: number;
|
|
56
|
+
export declare const DELEGATION_COMPACTION_HIGH_WATER_BYTES: number;
|
|
57
|
+
/** Hard validation bound for the checkpoint file on every read. */
|
|
58
|
+
export declare const MAX_CHECKPOINT_BYTES: number;
|
|
59
|
+
/** Hard validation bound for live (non-summary) records in a checkpoint. */
|
|
60
|
+
export declare const MAX_CHECKPOINT_RECORDS = 2048;
|
|
61
|
+
/**
|
|
62
|
+
* Closed-record summaries younger than this are never evicted to meet the
|
|
63
|
+
* checkpoint byte budget — evicting them would let a replayed dispatch of a
|
|
64
|
+
* recently closed session be recorded as fresh (double delivery). Over-budget
|
|
65
|
+
* young state skips compaction and surfaces pressure instead.
|
|
66
|
+
*/
|
|
67
|
+
export declare const TOMBSTONE_MIN_AGE_MS: number;
|
|
32
68
|
export type RecoveryOwnershipScanResult<T> = {
|
|
33
69
|
status: 'ok';
|
|
34
70
|
owners: T[];
|
|
71
|
+
/** How the primary store was reconstructed (issue #2034); absent for pre-checkpoint scans. */
|
|
72
|
+
source?: 'checkpoint+tail' | 'checkpoint+ledger-suffix' | 'legacy-ledger';
|
|
35
73
|
} | {
|
|
36
74
|
status: 'uncertain';
|
|
37
75
|
reason: string;
|
|
76
|
+
/**
|
|
77
|
+
* Best-known interpretation mode at failure time; `'unknown'` when the
|
|
78
|
+
* manifest/checkpoint state itself was unreadable (issue #2034 — the
|
|
79
|
+
* durable recovery observation must not claim a wrong source).
|
|
80
|
+
*/
|
|
81
|
+
source?: 'checkpoint+tail' | 'checkpoint+ledger-suffix' | 'legacy-ledger' | 'unknown';
|
|
82
|
+
/** Operator remediation guidance, when the failure mode has one. */
|
|
83
|
+
repairHint?: string;
|
|
38
84
|
};
|
|
39
85
|
/** An abandoned ingestion lease may be reclaimed after this bounded interval. */
|
|
40
86
|
export declare const BACKGROUND_INGESTION_LEASE_MS = 30000;
|
|
87
|
+
/**
|
|
88
|
+
* Canonical default staleness horizon for a tracked background delegation: a
|
|
89
|
+
* record whose `updatedAt` has not advanced in this long is treated as
|
|
90
|
+
* abandoned (its backing process died without ever writing a terminal
|
|
91
|
+
* snapshot) and may be swept to `stale`.
|
|
92
|
+
*
|
|
93
|
+
* 30 minutes is the value this subsystem already shipped — it was duplicated as
|
|
94
|
+
* a module-local literal in `src/tools/dispatch-lanes.ts` and as the
|
|
95
|
+
* `hooks.background_pending_timeout_minutes` schema default. It lives here so
|
|
96
|
+
* every consumer agrees on one number: this module imports nothing from
|
|
97
|
+
* `dispatch-lanes.ts` or `pr-workflow-gate.ts`, so both can reference it
|
|
98
|
+
* without an import cycle.
|
|
99
|
+
*/
|
|
100
|
+
export declare const DEFAULT_STALE_DELEGATION_TIMEOUT_MS: number;
|
|
41
101
|
export type BackgroundDelegationStatus = 'pending' | 'running' | 'ingesting' | 'ingestion_error' | 'completed' | 'error' | 'cancelled' | 'stale' | 'consumed';
|
|
102
|
+
/**
|
|
103
|
+
* The status classes the stale sweep is allowed to finalize to `stale`.
|
|
104
|
+
*
|
|
105
|
+
* Deliberately a subset of {@link BackgroundDelegationStatus}: a caller may
|
|
106
|
+
* *narrow* the sweep but can never widen it to a status the sweep was never
|
|
107
|
+
* meant to touch (`completed`, `consumed`, `ingesting`, ...).
|
|
108
|
+
*/
|
|
109
|
+
export type SweepableDelegationStatus = 'pending' | 'running' | 'ingestion_error';
|
|
110
|
+
/**
|
|
111
|
+
* Default sweep scope — the exact set the sweep has always finalized.
|
|
112
|
+
*
|
|
113
|
+
* `ingestion_error` is included here because the pre-existing lazy-maintenance
|
|
114
|
+
* caller (`recordPendingDelegation`) relies on it: an ingestion that never
|
|
115
|
+
* retried within the horizon is genuinely abandoned from that caller's point of
|
|
116
|
+
* view. Callers for whom `ingestion_error` is still *retryable* — the ingestion
|
|
117
|
+
* claim gate admits `completed` and `ingestion_error` only, so the `stale` flip
|
|
118
|
+
* is irreversible — must pass a narrowed set instead.
|
|
119
|
+
*/
|
|
120
|
+
export declare const DEFAULT_SWEEPABLE_DELEGATION_STATUSES: ReadonlySet<SweepableDelegationStatus>;
|
|
42
121
|
export interface BackgroundDelegationRecord {
|
|
43
122
|
schemaVersion: 1 | 2 | 3;
|
|
44
123
|
/** Subagent session id from the dispatch envelope — the correlation key. */
|
|
@@ -218,20 +297,81 @@ export interface BackgroundCoderReservation {
|
|
|
218
297
|
createdAt: number;
|
|
219
298
|
updatedAt: number;
|
|
220
299
|
}
|
|
300
|
+
export interface BackgroundDelegationCheckpoint {
|
|
301
|
+
schemaVersion: 1;
|
|
302
|
+
/** Monotonic checkpoint sequence for this store. */
|
|
303
|
+
sequence: number;
|
|
304
|
+
/** Diagnostics-only identity of the writing process (never validated). */
|
|
305
|
+
writerId: string;
|
|
306
|
+
/** Resolved project root this checkpoint is bound to. */
|
|
307
|
+
rootPath: string;
|
|
308
|
+
createdAt: number;
|
|
309
|
+
/** Byte length of the ledger at the cut. */
|
|
310
|
+
cutLedgerBytes: number;
|
|
311
|
+
/** sha256 of the ledger bytes [0..cutLedgerBytes) at the cut. */
|
|
312
|
+
cutLedgerDigest: string;
|
|
313
|
+
/** Live full records (bounded by MAX_CHECKPOINT_RECORDS). */
|
|
314
|
+
records: BackgroundDelegationRecord[];
|
|
315
|
+
/** Compact closed-record summaries, byte-budget governed. */
|
|
316
|
+
closed: BackgroundDelegationRecord[];
|
|
317
|
+
audit: DelegationCheckpointAuditSummary;
|
|
318
|
+
payloadChecksum: string;
|
|
319
|
+
}
|
|
320
|
+
export interface BackgroundDelegationManifest {
|
|
321
|
+
schemaVersion: 1;
|
|
322
|
+
sequence: number;
|
|
323
|
+
checkpointChecksum: string;
|
|
324
|
+
writerId: string;
|
|
325
|
+
rootPath: string;
|
|
326
|
+
updatedAt: number;
|
|
327
|
+
}
|
|
328
|
+
export declare const _checkpointInternals: {
|
|
329
|
+
renameWithRetry: (from: string, to: string) => void;
|
|
330
|
+
renameOnce: (from: string, to: string) => void;
|
|
331
|
+
syncSleep: (ms: number) => void;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* True when a record still owns an unsettled worktree (mirrors
|
|
335
|
+
* init-orphan-recovery's protection predicate — exported so both sites share
|
|
336
|
+
* ONE definition; drift here changes which worktrees orphan cleanup protects).
|
|
337
|
+
*/
|
|
338
|
+
export declare function isUnsettledWorktreeOwner(record: BackgroundDelegationRecord): boolean;
|
|
339
|
+
export interface CompactBackgroundDelegationsResult {
|
|
340
|
+
status: 'compacted' | 'skipped' | 'uncertain';
|
|
341
|
+
reason?: string;
|
|
342
|
+
sequence?: number;
|
|
343
|
+
tailBytes?: number;
|
|
344
|
+
checkpointBytes?: number;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Compact the delegation ledger: checkpoint the folded authoritative state,
|
|
348
|
+
* publish it via the manifest, and roll the ledger to the post-cut tail.
|
|
349
|
+
* Runs under the store lock (issue #2034 requirement 1).
|
|
350
|
+
*/
|
|
351
|
+
export declare function compactBackgroundDelegations(directory: string, options?: {
|
|
352
|
+
force?: boolean;
|
|
353
|
+
}): Promise<CompactBackgroundDelegationsResult>;
|
|
221
354
|
/**
|
|
222
355
|
* Read and fold the store to the latest snapshot per correlationId. Lock-free and
|
|
223
|
-
* defensive: a missing file yields an empty list, and malformed/partial lines are
|
|
224
|
-
* (never throws). Records are returned in first-seen correlationId order.
|
|
356
|
+
* defensive: a missing file yields an empty list, and malformed/partial lines are
|
|
357
|
+
* skipped (never throws). Records are returned in first-seen correlationId order.
|
|
358
|
+
*
|
|
359
|
+
* Checkpoint-aware (issue #2034): when a published checkpoint exists, the fold is
|
|
360
|
+
* checkpoint summaries + the bounded transition tail. When the authoritative
|
|
361
|
+
* state is uncertain (invalid checkpoint/manifest with a rolled tail), this
|
|
362
|
+
* returns [] — the strict recovery scan is the fail-closed authority.
|
|
225
363
|
*
|
|
226
|
-
* Cost: O(
|
|
227
|
-
*
|
|
228
|
-
* concurrent background delegations, and the on-disk log is small).
|
|
364
|
+
* Cost: O(checkpoint + tail lines) per call. The tail is bounded by the
|
|
365
|
+
* compaction high-water mark in normal operation.
|
|
229
366
|
*/
|
|
230
367
|
export declare function readDelegations(directory: string): BackgroundDelegationRecord[];
|
|
231
368
|
/**
|
|
232
|
-
* Strict startup-recovery view of the primary
|
|
369
|
+
* Strict startup-recovery view of the primary store. Unlike the ordinary
|
|
233
370
|
* advisory reader, this never treats unreadable, oversized, or malformed owner
|
|
234
371
|
* data as absence: destructive orphan cleanup must fail closed on uncertainty.
|
|
372
|
+
* Checkpoint-aware: folds checkpoint + the applicable bounded tail region and
|
|
373
|
+
* rejects corrupt or ambiguous cuts (issue #2034). Remains synchronous —
|
|
374
|
+
* callers depend on it.
|
|
235
375
|
*/
|
|
236
376
|
export declare function scanDelegationsForRecovery(directory: string): RecoveryOwnershipScanResult<BackgroundDelegationRecord>;
|
|
237
377
|
/** Returns the folded record for a correlationId, or null. Lock-free read. */
|
|
@@ -398,8 +538,16 @@ export declare function findOpenAsyncLaneBatches(directory: string): BackgroundD
|
|
|
398
538
|
/**
|
|
399
539
|
* Public stale sweep: acquires the store lock and marks overdue pendings as `stale`.
|
|
400
540
|
* Best-effort; returns the number swept (0 on lock timeout / error).
|
|
541
|
+
*
|
|
542
|
+
* `options.statuses` narrows which status classes may be finalized; omitting it
|
|
543
|
+
* preserves the historical scope ({@link DEFAULT_SWEEPABLE_DELEGATION_STATUSES}).
|
|
544
|
+
* The sweep is directory-wide with no session or mode filter, so a caller whose
|
|
545
|
+
* own decision covers only some status classes must narrow accordingly rather
|
|
546
|
+
* than finalizing records it never reasoned about.
|
|
401
547
|
*/
|
|
402
|
-
export declare function sweepStaleDelegations(directory: string, timeoutMs: number
|
|
548
|
+
export declare function sweepStaleDelegations(directory: string, timeoutMs: number, options?: {
|
|
549
|
+
statuses?: ReadonlySet<SweepableDelegationStatus>;
|
|
550
|
+
}): Promise<number>;
|
|
403
551
|
export interface BackgroundDelegationFallbackArtifact {
|
|
404
552
|
schemaVersion: 1;
|
|
405
553
|
correlationId: string;
|
|
@@ -207,6 +207,16 @@ export interface BuildPrReviewTriggerReceiptV2Args {
|
|
|
207
207
|
rows: unknown;
|
|
208
208
|
/** Receipt-level degradation disclosure; ledger rows stay untouched so the frozen-ledger digest is unaffected. */
|
|
209
209
|
coverage_degradations?: TriggerCoverageDegradation[];
|
|
210
|
+
/**
|
|
211
|
+
* How `base_sha` was verified for this receipt. `live` means the writer
|
|
212
|
+
* re-derived the merge base with git at write time; `bound_fallback` means
|
|
213
|
+
* that re-derivation was UNAVAILABLE and the writer accepted the caller's
|
|
214
|
+
* scope solely because it exactly equalled the durably bound, bind-time
|
|
215
|
+
* verified review scope. Optional for the same reason
|
|
216
|
+
* `coverage_degradations` is: the field is receipt-level disclosure, and
|
|
217
|
+
* making it required would break every existing builder call site.
|
|
218
|
+
*/
|
|
219
|
+
base_verification?: 'live' | 'bound_fallback';
|
|
210
220
|
}
|
|
211
221
|
export declare function buildPrReviewTriggerReceiptV2(input: BuildPrReviewTriggerReceiptV2Args): {
|
|
212
222
|
run_id: string;
|
|
@@ -243,6 +253,7 @@ export declare function buildPrReviewTriggerReceiptV2(input: BuildPrReviewTrigge
|
|
|
243
253
|
source_lane_id: string;
|
|
244
254
|
reason: string;
|
|
245
255
|
}[];
|
|
256
|
+
base_verification?: "live" | "bound_fallback" | undefined;
|
|
246
257
|
};
|
|
247
258
|
export interface ParsedPrReviewTriggerReceipt {
|
|
248
259
|
schemaVersion: 0 | 1 | 2;
|
|
@@ -255,6 +266,12 @@ export interface ParsedPrReviewTriggerReceipt {
|
|
|
255
266
|
}>[];
|
|
256
267
|
/** Empty for pre-v2.2 receipts. Present entries mean the family's cited lane is provenance-valid but coverage-degraded. */
|
|
257
268
|
coverageDegradations: TriggerCoverageDegradation[];
|
|
269
|
+
/**
|
|
270
|
+
* Undefined for legacy receipts and for v2 receipts written before the field
|
|
271
|
+
* existed. `bound_fallback` means the writer could not re-derive the merge
|
|
272
|
+
* base live and accepted the bound scope instead; synthesis must disclose it.
|
|
273
|
+
*/
|
|
274
|
+
baseVerification?: 'live' | 'bound_fallback';
|
|
258
275
|
}
|
|
259
276
|
/**
|
|
260
277
|
* Bind every micro dispatch to one semantic ledger at bind time.
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
shouldRunOnStartup,
|
|
13
13
|
writeBackupArtifact,
|
|
14
14
|
writeDoctorArtifact
|
|
15
|
-
} from "./index-
|
|
16
|
-
import"./index-
|
|
15
|
+
} from "./index-evvbmbbv.js";
|
|
16
|
+
import"./index-3q9w6e6v.js";
|
|
17
17
|
import"./index-jqsfsqbx.js";
|
|
18
18
|
import"./index-z6xqpmqg.js";
|
|
19
19
|
import"./index-zjygnfay.js";
|