ushman-ledger 1.2.2 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -5
- package/ARCHITECTURE.md +8 -2
- package/CHANGELOG.md +11 -0
- package/README.md +37 -5
- package/TROUBLESHOOTING.md +17 -3
- package/dist/blobs.d.ts.map +1 -1
- package/dist/blobs.js +1 -1
- package/dist/builders.d.ts +33 -0
- package/dist/builders.d.ts.map +1 -1
- package/dist/builders.js +10 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +153 -43
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +45 -11
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +67 -30
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +2 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/lab-min.d.ts +1 -1
- package/dist/lab-min.d.ts.map +1 -1
- package/dist/lab-min.js +2 -1
- package/dist/list.d.ts +32 -0
- package/dist/list.d.ts.map +1 -1
- package/dist/list.js +1 -1
- package/dist/patch-resolver.d.ts.map +1 -1
- package/dist/patch-resolver.js +1 -1
- package/dist/process.d.ts +2 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +16 -0
- package/dist/read-index.d.ts +7 -7
- package/dist/read-index.d.ts.map +1 -1
- package/dist/read-index.js +13 -9
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +1 -2
- package/dist/recovery.d.ts +8 -0
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +142 -30
- package/dist/render/retro.d.ts.map +1 -1
- package/dist/render/retro.js +4 -1
- package/dist/runtime-config.d.ts +2 -0
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +14 -0
- package/dist/schema/entry-core.d.ts +5 -2
- package/dist/schema/entry-core.d.ts.map +1 -1
- package/dist/schema/entry-core.js +3 -0
- package/dist/schema/entry-read.d.ts +57 -0
- package/dist/schema/entry-read.d.ts.map +1 -1
- package/dist/schema/entry-read.js +9 -1
- package/dist/schema/entry-write.d.ts +51 -0
- package/dist/schema/entry-write.d.ts.map +1 -1
- package/dist/schema/entry-write.js +9 -1
- package/dist/storage/filesystem.d.ts +14 -2
- package/dist/storage/filesystem.d.ts.map +1 -1
- package/dist/storage/filesystem.js +206 -39
- package/dist/storage/lock.d.ts.map +1 -1
- package/dist/storage/lock.js +38 -16
- package/package.json +2 -1
package/AGENTS.md
CHANGED
|
@@ -29,11 +29,13 @@ An append-only ledger library and CLI for ushman v4 workspaces. It owns ledger s
|
|
|
29
29
|
5. `src/schema/entry-migrations.ts`
|
|
30
30
|
6. `src/schema/entry.ts`
|
|
31
31
|
7. `src/storage/filesystem.ts`
|
|
32
|
-
8. `src/
|
|
33
|
-
9. `src/
|
|
34
|
-
10. `src/
|
|
35
|
-
11. `src/
|
|
36
|
-
12. `src/
|
|
32
|
+
8. `src/recovery.ts`
|
|
33
|
+
9. `src/record.ts`
|
|
34
|
+
10. `src/handle.ts`
|
|
35
|
+
11. `src/runtime-config.ts`
|
|
36
|
+
12. `src/coverage.ts`
|
|
37
|
+
13. `src/doctor.ts`
|
|
38
|
+
14. `src/cli.ts`
|
|
37
39
|
|
|
38
40
|
## Commands
|
|
39
41
|
|
package/ARCHITECTURE.md
CHANGED
|
@@ -20,7 +20,9 @@ The same reconciliation path is used by reads, writes, coverage, doctor, render,
|
|
|
20
20
|
|
|
21
21
|
- `manifest.json`: append-order metadata, per-phase pointers, idempotency index, and archive metadata.
|
|
22
22
|
- `read-index.json`: durable lightweight scan index used by list/render/coverage/doctor.
|
|
23
|
+
- `external-temp-files/`: journals for custom render temp files created outside `.lab/ledger`.
|
|
23
24
|
- `pending/`: append journals used to replay incomplete commits.
|
|
25
|
+
- `pending-quarantine/`: unreplayable pending commit journals plus quarantine metadata.
|
|
24
26
|
- `pending-archives/`: archive journals used to adopt or discard incomplete archive writes.
|
|
25
27
|
- `blobs/`: content-addressed patch payloads keyed by SHA-256.
|
|
26
28
|
- `<phase>/`: append-only entry files per ledger phase.
|
|
@@ -30,6 +32,7 @@ The same reconciliation path is used by reads, writes, coverage, doctor, render,
|
|
|
30
32
|
- Entries are immutable once written. Corrections use `correction` records linked to the original entry.
|
|
31
33
|
- Each phase maintains its own `prevEntryId` chain so local append history is explicit and auditable.
|
|
32
34
|
- Idempotency is logical-content based by default and can be overridden with an explicit `idempotencyKey`.
|
|
35
|
+
- `stage-write` records treat `filePath` as the required primary covered artifact and may extend coverage with extra normalized `links.affectedFiles`.
|
|
33
36
|
- Patch payloads are de-duplicated by SHA-256 and stored once under `blobs/`.
|
|
34
37
|
|
|
35
38
|
## Read path
|
|
@@ -43,8 +46,8 @@ The same reconciliation path is used by reads, writes, coverage, doctor, render,
|
|
|
43
46
|
|
|
44
47
|
- Atomic writes use temp files and rename.
|
|
45
48
|
- Pending commit journals record the target sequence before the entry file and manifest can drift.
|
|
46
|
-
- Startup reconciliation replays pending commits in manifest order, rebuilds missing or stale read indexes, adopts verified archives, and cleans stale temp files.
|
|
47
|
-
- Manifest locks are reclaimed
|
|
49
|
+
- Startup reconciliation replays pending commits in manifest order, quarantines unreplayable pending commits, rebuilds missing or stale read indexes, adopts verified archives, and cleans stale temp files.
|
|
50
|
+
- Manifest locks are reclaimed after stale-owner or dead-owner checks, so a newer owner is not deleted during handoff.
|
|
48
51
|
- Re-opening the ledger or rerunning any CLI command triggers the same recovery path; there is no separate manual recovery subcommand.
|
|
49
52
|
|
|
50
53
|
## Scale and tuning
|
|
@@ -57,6 +60,8 @@ The default scan contract is intentionally conservative and can be tuned with en
|
|
|
57
60
|
- `USHMAN_LEDGER_READ_INDEX_REBUILD_CONCURRENCY`
|
|
58
61
|
- `USHMAN_LEDGER_COVERAGE_FILE_STAT_CONCURRENCY`
|
|
59
62
|
- `USHMAN_LEDGER_BLOB_HASH_CONCURRENCY`
|
|
63
|
+
- `USHMAN_LEDGER_DOCTOR_CHECKPOINT_MAX_AGE_MS`
|
|
64
|
+
- `USHMAN_LEDGER_DOCTOR_OPEN_ISSUE_MAX_AGE_MS`
|
|
60
65
|
- `USHMAN_LEDGER_MAX_PATCH_BYTES`
|
|
61
66
|
|
|
62
67
|
The benchmark entrypoint, `bun run bench:scale`, prints the active runtime config so measurements can be compared across different knob settings.
|
|
@@ -70,6 +75,7 @@ The benchmark entrypoint, `bun run bench:scale`, prints the active runtime confi
|
|
|
70
75
|
## Contributor map
|
|
71
76
|
|
|
72
77
|
- `src/blobs.ts`: patch blob storage, size limits, and digest/path validation.
|
|
78
|
+
- `src/storage/lock.ts`: manifest lock acquisition, stale-owner reclaim, and reclaim-marker turnover.
|
|
73
79
|
- `src/record.ts`: append pipeline and idempotency behavior.
|
|
74
80
|
- `src/recovery.ts`: pending journal replay, read-index rebuild, and temp cleanup.
|
|
75
81
|
- `src/read-index.ts`: durable scan index construction and maintenance.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0] - 2026-05-28
|
|
4
|
+
|
|
5
|
+
- Added `stage-write` ledger records for deterministic pipeline-owned candidate writes.
|
|
6
|
+
- `stage-write` now accepts `intake` alongside the later candidate-mutating stage ids so intake-owned writes such as auto-stubs and workspace runbooks can be recorded without falling back to patch semantics.
|
|
7
|
+
- Read-index coverage now treats `stage-write.filePath` the same as patch `affectedFiles`, so downstream coverage checks can distinguish stage output from operator edits without losing coverage accounting.
|
|
8
|
+
- Retro rendering now includes `stage-write` entries in the tool/action stream.
|
|
9
|
+
- Custom render outputs now journal their external temp files so startup recovery can clean stale crash leftovers outside `.lab/ledger`.
|
|
10
|
+
- Lock recovery now reclaims locks immediately when the recorded owner PID is no longer alive.
|
|
11
|
+
- Pending commit recovery now quarantines unreplayable journals and reports them through `doctor` instead of failing the whole reconciliation pass.
|
|
12
|
+
- Doctor stale-age windows for pre-change checkpoints and open issues are configurable through runtime environment variables.
|
|
13
|
+
|
|
3
14
|
## [1.1.0] - 2026-05-23
|
|
4
15
|
|
|
5
16
|
- Added `change-log` records, narrative note subkinds, and `migration-log-md` / `workspace-narrative-md` render targets.
|
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
appendSemanticCleanupSummaryNote,
|
|
34
34
|
type BuildRecordInput,
|
|
35
35
|
buildChangeLogRecord,
|
|
36
|
+
buildStageWriteRecord,
|
|
36
37
|
buildValidatorResultRecord,
|
|
37
38
|
deriveFilesChangedFromPatch,
|
|
38
39
|
getLedgerRuntimeConfig,
|
|
@@ -75,6 +76,17 @@ await ledger.record(
|
|
|
75
76
|
}),
|
|
76
77
|
);
|
|
77
78
|
|
|
79
|
+
await ledger.record(
|
|
80
|
+
buildStageWriteRecord({
|
|
81
|
+
emitter: { tool: 'ushman-seed', version: '1.0.0' },
|
|
82
|
+
filePath: 'src/generated/candidate.ts',
|
|
83
|
+
phase: 'seed',
|
|
84
|
+
rationale: 'Seed stage wrote the initial candidate artifact.',
|
|
85
|
+
stage: 'seed',
|
|
86
|
+
summary: 'seed candidate output',
|
|
87
|
+
}),
|
|
88
|
+
);
|
|
89
|
+
|
|
78
90
|
await ledger.record(
|
|
79
91
|
buildValidatorResultRecord({
|
|
80
92
|
emitter: { tool: 'ushman-doctor', version: '1.0.0' },
|
|
@@ -126,26 +138,33 @@ const buildRuntimeEventRecord = (input: RuntimeEventInput) => ({
|
|
|
126
138
|
```bash
|
|
127
139
|
ushman-ledger record --workspace=<ws> --kind=tool-invocation --phase=capture --summary="capture started"
|
|
128
140
|
ushman-ledger record --workspace=<ws> --kind=agent-patch --phase=cleanup --summary="capture git diff" --rationale="track working tree change" --diff-from-git=HEAD
|
|
141
|
+
ushman-ledger record --workspace=<ws> --kind=stage-write --phase=seed --summary="seed output" --rationale="pipeline wrote candidate" --file-path=src/generated/candidate.ts --stage=seed
|
|
129
142
|
ushman-ledger record --workspace=<ws> --kind=change-log --subkind=smoke --phase=cleanup --summary="scope git diff" --diff-from-git=HEAD --git-paths=src/main.ts,src/cli.ts --git-diff-timeout-ms=10000 --git-diff-max-buffer-bytes=20971520
|
|
130
143
|
ushman-ledger record --workspace=<ws> --kind=operator-decision --phase=cleanup --summary="manual override" --action=ledger-hand-edit --check-id=manual-review --rationale="operator edited the ledger after audit"
|
|
131
144
|
ushman-ledger record --workspace=<ws> --kind=change-log --subkind=semantic-cleanup --phase=cleanup --summary="split schema modules" --diff=/tmp/change.patch --hypothesis="smaller schema modules keep the public API stable" --commands=$'bun test\nbun run typecheck' --smoke-result=pass --parity-status=green --rollback-plan="revert the schema split"
|
|
132
145
|
ushman-ledger note regression --workspace=<ws> --phase=cleanup --summary="runtime drift" --body=/tmp/note.md
|
|
133
146
|
ushman-ledger note cleanup-wave --workspace=<ws> --phase=cleanup --summary="wave 1" --body=/tmp/narrative.md
|
|
134
147
|
ushman-ledger list --workspace=<ws> --json
|
|
148
|
+
ushman-ledger list --workspace=<ws> --json --progress
|
|
135
149
|
ushman-ledger render --workspace=<ws> --to=retro
|
|
136
150
|
ushman-ledger render --workspace=<ws> --to=migration-log-md
|
|
137
151
|
ushman-ledger render --workspace=<ws> --to=workspace-narrative-md
|
|
152
|
+
ushman-ledger render --workspace=<ws> --to=retro --out=/tmp/retro.md --quiet
|
|
138
153
|
ushman-ledger render --workspace=<ws> --to=jsonl --out=/tmp/ledger.jsonl
|
|
139
154
|
ushman-ledger render --workspace=<ws> --to=dependency-graph --out=/tmp/ledger.mmd
|
|
140
155
|
ushman-ledger archive --workspace=<ws> --out=/tmp/ledger.tgz
|
|
156
|
+
ushman-ledger archive --workspace=<ws> --out=/tmp/ledger.tgz --progress
|
|
141
157
|
ushman-ledger doctor --workspace=<ws>
|
|
142
158
|
ushman-ledger doctor --workspace=<ws> --json
|
|
159
|
+
ushman-ledger doctor --workspace=<ws> --quiet
|
|
143
160
|
```
|
|
144
161
|
|
|
145
|
-
Valid record kinds: `tool-invocation`, `agent-patch`, `operator-patch`, `operator-decision`, `validator-result`, `runtime-event`, `note`, `correction`, `strip-decision-reverted`, `change-log`
|
|
162
|
+
Valid record kinds: `tool-invocation`, `stage-write`, `agent-patch`, `operator-patch`, `operator-decision`, `validator-result`, `runtime-event`, `note`, `correction`, `strip-decision-reverted`, `change-log`
|
|
146
163
|
|
|
147
164
|
Valid phases: `capture`, `intake`, `seed`, `vendor-extract`, `cleanup`, `parity`, `characterize`, `equiv`, `analyze`, `recover`, `ship`, `migration`
|
|
148
165
|
|
|
166
|
+
Valid `stage-write` stages: `seed`, `vendor-extract`, `cleanup`, `candidate-promotion`
|
|
167
|
+
|
|
149
168
|
Valid note subkinds: `regression`, `automation`, `retro`, `operator`, `tooling-gap`, `cleanup-wave`, `verified-flow`, `open-issue`, `decomposition-wave`, `semantic-cleanup-summary`
|
|
150
169
|
|
|
151
170
|
Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `migration-log-md`, `workspace-narrative-md`
|
|
@@ -169,6 +188,12 @@ Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `mi
|
|
|
169
188
|
`render()` still returns a string for in-memory callers. `renderTo()` is the bounded-output alternative for large ledgers and can write to a callback or the canonical render file on disk.
|
|
170
189
|
`renderTo()` writers receive sequential chunks, can return synchronously or asynchronously, and should throw only when the render should abort.
|
|
171
190
|
|
|
191
|
+
## CLI quiet and progress modes
|
|
192
|
+
|
|
193
|
+
- `--progress` writes concise progress lines to stderr for long-running `list`, `render`, `archive`, and `doctor` CLI operations. Stdout remains reserved for the command result, so `list --json --progress` still emits parseable JSON.
|
|
194
|
+
- `--quiet` suppresses verbose human output on those commands. `doctor --quiet` prints `ok` or one finding code per line; `archive --quiet` and `render --quiet` print `ok` on success; `list --quiet` prints one entry id per line for non-JSON output.
|
|
195
|
+
- `--quiet` takes precedence over `--progress`. For render targets without a canonical ledger render file, such as `jsonl` and `dependency-graph`, `render --quiet` requires `--out`.
|
|
196
|
+
|
|
172
197
|
## Workspace prerequisite
|
|
173
198
|
|
|
174
199
|
`openLedger()` and the CLI expect a valid ushman v4 workspace with `.lab/lab.json` already present.
|
|
@@ -184,14 +209,16 @@ Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `mi
|
|
|
184
209
|
- `operator-decision` entries capture `{ action, checkId?, rationale }` in `payload`. `action` is one of `bypass-doctor`, `skip-check`, `override-strip-decision`, `override-ship-state`, `manual-parity-assertion`, `ledger-hand-edit`, `escalation`.
|
|
185
210
|
- `strip-decision-reverted` entries capture `{ stripDecisionId, rationale, invalidatedStages? }`.
|
|
186
211
|
- `correction` entries require `links.correctsLedgerId` pointing at the entry they correct.
|
|
212
|
+
- `stage-write` entries capture `{ filePath, rationale, stage }` for deterministic pipeline-owned writes. `phase` records where the ledger event happened; `stage` records the pipeline stage that produced the artifact.
|
|
187
213
|
- Patch entries (`agent-patch`, `operator-patch`) store a `diff` blob reference and a `rationale`. Patch text is stored once under `.lab/ledger/blobs/` and shared by hash.
|
|
188
214
|
|
|
189
215
|
## Links and coverage
|
|
190
216
|
|
|
191
217
|
- `links.affectedFiles` should contain normalized workspace-relative paths for files changed by an `agent-patch` or `operator-patch`.
|
|
218
|
+
- `stage-write.filePath` is always treated as covered output. If one stage write should cover additional normalized paths, include them in `links.affectedFiles`; coverage merges both sources.
|
|
192
219
|
- Use forward slashes, do not prefix paths with `./`, and do not include trailing slashes or `..` segments.
|
|
193
220
|
- Coverage only considers candidate workspace files modified after workspace initialization.
|
|
194
|
-
- A modified file is considered covered when
|
|
221
|
+
- A modified file is considered covered when a patch entry lists it in `links.affectedFiles` or a `stage-write` entry names it through `filePath`/`links.affectedFiles`.
|
|
195
222
|
- Coverage is backed by a durable read index so repeated coverage runs do not rescan every patch entry.
|
|
196
223
|
|
|
197
224
|
## Append chain and concurrency
|
|
@@ -200,21 +227,22 @@ Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `mi
|
|
|
200
227
|
- Manifest updates are serialized through a global ledger lock.
|
|
201
228
|
- Appends use a pending-commit journal so entry files, the manifest, and the durable read index can be replayed after crashes.
|
|
202
229
|
- Open, read, and append paths reconcile unfinished commits before serving ledger data.
|
|
203
|
-
- Corrupt or
|
|
230
|
+
- Corrupt, stale, or dead-owner manifest locks are reclaimed automatically with compare-and-swap style quarantine semantics.
|
|
204
231
|
|
|
205
232
|
## Crash recovery
|
|
206
233
|
|
|
207
234
|
- Pending commit journals live under `.lab/ledger/pending/`.
|
|
235
|
+
- Pending commit journals that cannot be replayed are moved to `.lab/ledger/pending-quarantine/` and surfaced by `doctor`.
|
|
208
236
|
- Pending archive journals live under `.lab/ledger/pending-archives/`.
|
|
209
237
|
- Startup reconciliation replays journaled appends in manifest sequence order.
|
|
210
238
|
- Startup reconciliation also rebuilds a missing or stale `read-index.json` from manifest sequence order.
|
|
211
239
|
- Verified pending archives are adopted into the manifest on startup; corrupt or partial pending archives are deleted.
|
|
212
|
-
- Stale temp files are cleaned for phase entries, the manifest, blobs, the read index, and render outputs.
|
|
240
|
+
- Stale temp files are cleaned for phase entries, the manifest, blobs, the read index, canonical render outputs, and tracked custom render outputs.
|
|
213
241
|
|
|
214
242
|
## Recovery & Troubleshooting
|
|
215
243
|
|
|
216
244
|
- `.lab/ledger/pending/` contains append journals that let the ledger recover incomplete writes after crashes. Do not edit these files by hand.
|
|
217
|
-
- If startup
|
|
245
|
+
- If startup moves a pending commit to `.lab/ledger/pending-quarantine/`, inspect the `doctor` finding and restore the journal only when its entry, sequence, and manifest base are known to be safe.
|
|
218
246
|
- If `doctor` reports manifest or blob corruption, fix the underlying entry/blob mismatch first and rerun `doctor` before attempting `archive`.
|
|
219
247
|
|
|
220
248
|
## Scan behavior
|
|
@@ -249,7 +277,9 @@ Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `mi
|
|
|
249
277
|
.manifest.lock
|
|
250
278
|
manifest.json
|
|
251
279
|
read-index.json
|
|
280
|
+
external-temp-files/
|
|
252
281
|
pending/
|
|
282
|
+
pending-quarantine/
|
|
253
283
|
pending-archives/
|
|
254
284
|
blobs/
|
|
255
285
|
render.md
|
|
@@ -290,6 +320,8 @@ bun run bench:scale
|
|
|
290
320
|
- `USHMAN_LEDGER_READ_INDEX_REBUILD_CONCURRENCY`: concurrent entry reads used while rebuilding `read-index.json`. Defaults to `USHMAN_LEDGER_SCAN_CONCURRENCY`.
|
|
291
321
|
- `USHMAN_LEDGER_COVERAGE_FILE_STAT_CONCURRENCY`: concurrent `stat()` calls during coverage scans. Defaults to `USHMAN_LEDGER_SCAN_CONCURRENCY`.
|
|
292
322
|
- `USHMAN_LEDGER_BLOB_HASH_CONCURRENCY`: concurrent blob integrity hashes during `doctor`. Defaults to `USHMAN_LEDGER_SCAN_CONCURRENCY`.
|
|
323
|
+
- `USHMAN_LEDGER_DOCTOR_CHECKPOINT_MAX_AGE_MS`: stale window for `pre-change-checkpoint` follow-up findings. Default `86400000`.
|
|
324
|
+
- `USHMAN_LEDGER_DOCTOR_OPEN_ISSUE_MAX_AGE_MS`: stale window for unresolved `open-issue` note findings. Default `2592000000`.
|
|
293
325
|
- `USHMAN_LEDGER_MAX_PATCH_BYTES`: maximum accepted patch/blob input size in bytes. Default `10485760`.
|
|
294
326
|
|
|
295
327
|
All runtime tuning values must be positive integers. Invalid values fail fast with an explicit error so automation does not silently run with an unexpected fallback.
|
package/TROUBLESHOOTING.md
CHANGED
|
@@ -127,18 +127,28 @@ Action:
|
|
|
127
127
|
|
|
128
128
|
### `pre-change-checkpoint-stale`
|
|
129
129
|
|
|
130
|
-
Meaning: a pre-change checkpoint aged past
|
|
130
|
+
Meaning: a pre-change checkpoint aged past the configured stale window without a follow-up entry using the same `idempotencyKey`. The default window is 24 hours.
|
|
131
131
|
|
|
132
132
|
Action:
|
|
133
133
|
- Append the follow-up change-log entry, or close the stale checkpoint with a correction entry explaining the abandoned work.
|
|
134
134
|
|
|
135
135
|
### `open-issue-stale`
|
|
136
136
|
|
|
137
|
-
Meaning: an `open-issue` note is older than
|
|
137
|
+
Meaning: an `open-issue` note is older than the configured stale window and has no correction/supersession link. The default window is 30 days.
|
|
138
138
|
|
|
139
139
|
Action:
|
|
140
140
|
- Append a correction or superseding note linking back to the old issue once the follow-up is complete.
|
|
141
141
|
|
|
142
|
+
### `pending-commit-quarantined`
|
|
143
|
+
|
|
144
|
+
Meaning: startup recovery found a pending commit journal that could not be parsed, replayed, or reconciled with the current manifest, so it moved the journal to `.lab/ledger/pending-quarantine/` and continued reconciling the rest of the ledger.
|
|
145
|
+
|
|
146
|
+
Action:
|
|
147
|
+
- Inspect the finding metadata and matching quarantine files.
|
|
148
|
+
- Start with `ushman-ledger doctor --workspace="$WS" --json` so the finding metadata shows the quarantined file path and recorded reason.
|
|
149
|
+
- Restore the journal to `.lab/ledger/pending/` only if its entry, sequence, and manifest base are known to be safe.
|
|
150
|
+
- Otherwise keep or remove the quarantined file after recording an operator decision for the recovery outcome.
|
|
151
|
+
|
|
142
152
|
### `read-failure`
|
|
143
153
|
|
|
144
154
|
Meaning: the ledger could not be parsed or reconciled cleanly before checks started.
|
|
@@ -159,12 +169,16 @@ Action:
|
|
|
159
169
|
|
|
160
170
|
### Ledger lock held by a dead process
|
|
161
171
|
|
|
162
|
-
Rerun the original ledger command first. Lock reclamation
|
|
172
|
+
Rerun the original ledger command first. Lock reclamation checks the recorded owner PID and stale age during normal startup and append flows, so you usually do not need to delete lock files by hand.
|
|
163
173
|
|
|
164
174
|
### Manifest and disk disagree after a crash
|
|
165
175
|
|
|
166
176
|
Re-open the ledger first so pending commits can be replayed. If `doctor` still reports `manifest-entry-missing-on-disk` or `manifest-entry-location-missing`, repair the missing entry file or manifest location before archiving.
|
|
167
177
|
|
|
178
|
+
### Custom doctor stale windows
|
|
179
|
+
|
|
180
|
+
Use `USHMAN_LEDGER_DOCTOR_CHECKPOINT_MAX_AGE_MS` to tune `pre-change-checkpoint-stale` and `USHMAN_LEDGER_DOCTOR_OPEN_ISSUE_MAX_AGE_MS` to tune `open-issue-stale`. Both values are positive integer millisecond windows and keep the default behavior when unset.
|
|
181
|
+
|
|
168
182
|
### Manual ledger edits
|
|
169
183
|
|
|
170
184
|
Prefer appending `correction` or `operator-decision` records instead of editing historical entry files directly. If historical files were edited already, use `doctor` to identify the damaged chain or manifest pointers before appending new records.
|
package/dist/blobs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"AAsDA,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,WAKnD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,WAAW,MAAM,EAAE,aAAa,MAAM,WAOhF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAU,WAAW,MAAM,oBAO5D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,eAAe,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,eAAe,CAmBtG,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAU,eAAe,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,eAAe,CAE9G,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,eAAe,MAAM,EAAE,QAAQ,MAAM,WACN,CAAC"}
|
package/dist/blobs.js
CHANGED
|
@@ -31,7 +31,7 @@ const countPatchLines = (patchText) => {
|
|
|
31
31
|
});
|
|
32
32
|
return { addedLines, removedLines };
|
|
33
33
|
};
|
|
34
|
-
const formatPatchLimitError = ({ bytes, limitBytes, sourceLabel }) => `Patch input from ${sourceLabel} is ${bytes} bytes, exceeding the configured limit of ${limitBytes} bytes. Reduce the diff size or increase USHMAN_LEDGER_MAX_PATCH_BYTES.`;
|
|
34
|
+
const formatPatchLimitError = ({ bytes, limitBytes, sourceLabel, }) => `Patch input from ${sourceLabel} is ${bytes} bytes, exceeding the configured limit of ${limitBytes} bytes. Reduce the diff size or increase USHMAN_LEDGER_MAX_PATCH_BYTES.`;
|
|
35
35
|
const buildBlobPath = (workspaceRoot, sha256) => {
|
|
36
36
|
const paths = resolveLedgerPaths(workspaceRoot);
|
|
37
37
|
return path.join(paths.blobsDir, sha256.slice(0, 2), `${sha256}.patch`);
|
package/dist/builders.d.ts
CHANGED
|
@@ -147,6 +147,39 @@ export declare const buildChangeLogRecord: (input: BuildRecordInput<Extract<Ledg
|
|
|
147
147
|
phase: "capture" | "intake" | "seed" | "vendor-extract" | "cleanup" | "parity" | "characterize" | "equiv" | "analyze" | "recover" | "ship" | "migration";
|
|
148
148
|
summary: string;
|
|
149
149
|
};
|
|
150
|
+
/** Build a `stage-write` record. */
|
|
151
|
+
export declare const buildStageWriteRecord: (input: BuildRecordInput<Extract<LedgerRecord, {
|
|
152
|
+
kind: "stage-write";
|
|
153
|
+
}>>) => {
|
|
154
|
+
filePath: string;
|
|
155
|
+
kind: "stage-write";
|
|
156
|
+
rationale: string;
|
|
157
|
+
stage: "intake" | "seed" | "vendor-extract" | "cleanup" | "candidate-promotion";
|
|
158
|
+
details?: {
|
|
159
|
+
[x: string]: unknown;
|
|
160
|
+
} | undefined;
|
|
161
|
+
emitter: {
|
|
162
|
+
tool: string;
|
|
163
|
+
user?: string | undefined;
|
|
164
|
+
version: string;
|
|
165
|
+
};
|
|
166
|
+
idempotencyKey?: string | undefined;
|
|
167
|
+
links?: ({
|
|
168
|
+
affectedFiles?: string[] | undefined;
|
|
169
|
+
blobs?: string[] | undefined;
|
|
170
|
+
briefId?: string | undefined;
|
|
171
|
+
correctsLedgerId?: string | undefined;
|
|
172
|
+
gitRef?: string | undefined;
|
|
173
|
+
idempotencyKey?: string | undefined;
|
|
174
|
+
stripDecisionId?: string | undefined;
|
|
175
|
+
supersedesLedgerId?: string | undefined;
|
|
176
|
+
validatorVerdictId?: string | undefined;
|
|
177
|
+
} & {
|
|
178
|
+
[key: string]: unknown;
|
|
179
|
+
}) | undefined;
|
|
180
|
+
phase: "capture" | "intake" | "seed" | "vendor-extract" | "cleanup" | "parity" | "characterize" | "equiv" | "analyze" | "recover" | "ship" | "migration";
|
|
181
|
+
summary: string;
|
|
182
|
+
};
|
|
150
183
|
/** Build a `strip-decision-reverted` record. */
|
|
151
184
|
export declare const buildStripDecisionRevertedRecord: (input: BuildRecordInput<Extract<LedgerRecord, {
|
|
152
185
|
kind: "strip-decision-reverted";
|
package/dist/builders.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,KAAK,YAAY,EAKpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,gBAAgB,CAAC,OAAO,SAAS,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,2BAA2B,GACpC,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAM3E,CAAC;AAEP,yCAAyC;AACzC,eAAO,MAAM,0BAA0B,GACnC,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK1E,CAAC;AAEP,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,GAAI,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CAItG,CAAC;AAEP,mCAAmC;AACnC,eAAO,MAAM,oBAAoB,GAAI,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIrG,CAAC;AAEP,oCAAoC;AACpC,eAAO,MAAM,qBAAqB,GAAI,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQvG,CAAC;AAEP,gDAAgD;AAChD,eAAO,MAAM,gCAAgC,GACzC,OAAO,gBAAgB,CAAC,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,yBAAyB,CAAA;CAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKjF,CAAC"}
|
package/dist/builders.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
|
-
import { ChangeLogRecordSchema, CorrectionRecordSchema, OperatorDecisionRecordSchema, StripDecisionRevertedRecordSchema, ValidatorResultRecordSchema, } from "./schema/entry.js";
|
|
2
|
+
import { ChangeLogRecordSchema, CorrectionRecordSchema, OperatorDecisionRecordSchema, StageWriteRecordSchema, StripDecisionRevertedRecordSchema, ValidatorResultRecordSchema, } from "./schema/entry.js";
|
|
3
3
|
/** Build an `operator-decision` record with a validated structured payload. */
|
|
4
4
|
export const buildOperatorDecisionRecord = (input) => v.parse(OperatorDecisionRecordSchema, {
|
|
5
5
|
...input,
|
|
@@ -21,6 +21,15 @@ export const buildChangeLogRecord = (input) => v.parse(ChangeLogRecordSchema, {
|
|
|
21
21
|
...input,
|
|
22
22
|
kind: 'change-log',
|
|
23
23
|
});
|
|
24
|
+
/** Build a `stage-write` record. */
|
|
25
|
+
export const buildStageWriteRecord = (input) => v.parse(StageWriteRecordSchema, {
|
|
26
|
+
...input,
|
|
27
|
+
kind: 'stage-write',
|
|
28
|
+
links: {
|
|
29
|
+
...(input.links ?? {}),
|
|
30
|
+
affectedFiles: [...new Set([...(input.links?.affectedFiles ?? []), input.filePath])],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
24
33
|
/** Build a `strip-decision-reverted` record. */
|
|
25
34
|
export const buildStripDecisionRevertedRecord = (input) => v.parse(StripDecisionRevertedRecordSchema, {
|
|
26
35
|
...input,
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAmEA,KAAK,UAAU,GAAG;IACd,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE;QACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG,aAAa,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC1C,CAAC;AAomCF,eAAO,MAAM,YAAY,GAAU,MAAM,SAAS,MAAM,EAAE,EAAE,UAAS,OAAO,CAAC,UAAU,CAAM,KAAG,OAAO,CAAC,MAAM,CAqC7G,CAAC;AAEF,eAAO,MAAM,IAAI,GAAU,OAAM,SAAS,MAAM,EAA0B,KAAG,OAAO,CAAC,MAAM,CAE1F,CAAC"}
|