wowbagger 0.1.0-alpha.8 → 0.5.0-beta.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/CHANGELOG.md +470 -0
- package/README.md +220 -79
- package/assets/wowbagger-v1-more-whimsical.jpg +0 -0
- package/assets/wowbagger-v2-less-whimsical.jpg +0 -0
- package/assets/wowbagger-v3-herding-agent-cats.jpg +0 -0
- package/assets/wowbagger-v4-robot-agent-herding.jpg +0 -0
- package/assets/wowbagger-v5-typing-cats-circuit-staff.jpg +0 -0
- package/docs/adapter-contract.md +1 -1
- package/docs/host-contract.md +7 -1
- package/docs/mutation-contract.md +354 -82
- package/docs/work-claim-contract.md +466 -88
- package/package.json +8 -3
- package/schemas/core-capabilities-response.json +1 -1
- package/schemas/core-envelope.json +4 -3
- package/schemas/index.json +18 -0
- package/schemas/ledger-repair-proposal.json +170 -0
- package/schemas/ledger-repair-request.json +61 -0
- package/schemas/ledger-repair-response.json +90 -0
- package/skills/wowbagger/SKILL.md +250 -56
- package/src/adapter/core-probe.js +3 -4
- package/src/adapter/process-outcome.js +8 -1
- package/src/claim-capabilities.js +3 -3
- package/src/claim-coordinator.js +61 -12
- package/src/claim-journal.js +212 -7
- package/src/claim-prospective.js +1 -28
- package/src/claim-publication.js +412 -78
- package/src/claim-request.js +9 -0
- package/src/claim-store.js +9 -4
- package/src/cli.js +302 -56
- package/src/extensions.js +1 -0
- package/src/git-autocommit.js +106 -43
- package/src/git-reconciliation.js +74 -19
- package/src/git-worktrees.js +73 -0
- package/src/instrumentation.js +1 -0
- package/src/launch.js +2 -2
- package/src/ledger-repair.js +1170 -0
- package/src/mutation.js +73 -15
- package/src/reconciliation-classifier.js +117 -0
- package/src/report.js +11 -2
- package/src/version-drift.js +98 -0
- package/src/worktree-identity.js +165 -0
package/README.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
**The backlog may be infinite. The next item should not be ambiguous.**
|
|
4
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/lstutzman/wowbagger/main/assets/wowbagger-v5-typing-cats-circuit-staff.jpg" alt="Bowerick Wowbagger directing robotic agent cats typing at consoles with a circuit-lit shepherd's staff">
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
**Don't Panic!** The books that helped shape my childhood taught me to meet
|
|
10
|
+
absurd systems with curiosity, humor, and a reliable way to find the next
|
|
11
|
+
step. [Douglas Adams's Hitchhiker's Guide creations](https://douglasadams.com/creations/hhgg.html)
|
|
12
|
+
are part of that inspiration; Wowbagger is an independent work, not an
|
|
13
|
+
official or affiliated project.
|
|
14
|
+
|
|
5
15
|
Wowbagger is a work ledger for coding agents. Every backlog item is one
|
|
6
16
|
Markdown file in your repository; every lifecycle change is a reviewable Git
|
|
7
17
|
diff. There is no database, no hosted service, and no private agent memory to
|
|
@@ -20,10 +30,10 @@ agent to use those guarantees instead of hand-editing your Markdown.
|
|
|
20
30
|
|
|
21
31
|
**Start here:** [install the core and set up a ledger](#start-here).
|
|
22
32
|
|
|
23
|
-
> **Status:
|
|
24
|
-
> the `next` tag and on this repository's `v0.
|
|
25
|
-
> version this repository runs its own backlog on. The API
|
|
26
|
-
>
|
|
33
|
+
> **Status: beta, published, and self-hosted.** `0.5.0-beta.0` is on npm under
|
|
34
|
+
> the `next` tag and on this repository's `v0.5.0-beta.0` tag. It is the
|
|
35
|
+
> version this repository runs its own backlog on. The API remains pre-stable
|
|
36
|
+
> and can change before the first stable release.
|
|
27
37
|
>
|
|
28
38
|
> **Install with `@next`.** Every published release is a prerelease. The
|
|
29
39
|
> registry requires a `latest` dist-tag, so `latest` mirrors `next` — a bare
|
|
@@ -31,17 +41,25 @@ agent to use those guarantees instead of hand-editing your Markdown.
|
|
|
31
41
|
> older build — but `@next` is the documented install and the explicit
|
|
32
42
|
> statement that you accept a prerelease.
|
|
33
43
|
>
|
|
34
|
-
> **What is proved.**
|
|
35
|
-
> deterministic ready queue,
|
|
36
|
-
>
|
|
37
|
-
> `
|
|
38
|
-
>
|
|
39
|
-
>
|
|
40
|
-
>
|
|
41
|
-
>
|
|
42
|
-
>
|
|
43
|
-
>
|
|
44
|
-
>
|
|
44
|
+
> **What is proved.** Contract version **5** validates the complete Markdown
|
|
45
|
+
> ledger, selects a deterministic ready queue, exposes bounded `list` and
|
|
46
|
+
> lossless `inspect` projections, and publishes guarded `create`, `transition`,
|
|
47
|
+
> `patch`, `parent-migrate`, and `snooze` mutations. Mutations use exact-byte
|
|
48
|
+
> compare-and-swap, atomic no-clobber publication, and explicit reconciliation
|
|
49
|
+
> when a response is lost. Claims, fencing, adoption, prospective merge
|
|
50
|
+
> verification, and publication finalization coordinate cooperating writers
|
|
51
|
+
> without pretending to be an exclusive dispatch lock.
|
|
52
|
+
>
|
|
53
|
+
> `report` is a self-contained sequencing dashboard: **Work next**, **Attention**,
|
|
54
|
+
> facet filters, inline evidence, terminal history, area-diverse batches, and a
|
|
55
|
+
> 3D dependency graph. Version 2 report configurations add named custom views
|
|
56
|
+
> whose statistics, readiness, attention, evidence, graph, and drill-down all
|
|
57
|
+
> describe one filtered subset. Reports remain derived output, not mirrored
|
|
58
|
+
> ledger state.
|
|
59
|
+
>
|
|
60
|
+
> The core ships Claude Code, Codex, and OpenCode adapter packages on one shared
|
|
61
|
+
> engine. Read `capabilities --json` before relying on a target-specific claim;
|
|
62
|
+
> platform support is evidence-based, not inferred from whether a CLI starts.
|
|
45
63
|
>
|
|
46
64
|
> **What is not a lock.** A work claim is not an exclusive dispatch lease. On a
|
|
47
65
|
> provisioned Git-backed ledger, claims coordinate cooperating agents through a
|
|
@@ -53,31 +71,85 @@ agent to use those guarantees instead of hand-editing your Markdown.
|
|
|
53
71
|
> filesystem writes, hostile processes, other clones, and non-claim-aware tools
|
|
54
72
|
> still bypass the protocol.
|
|
55
73
|
|
|
74
|
+
## TL;DR for agents
|
|
75
|
+
|
|
76
|
+
Wowbagger is the core authority for a Git-native work ledger. Use it instead
|
|
77
|
+
of editing ledger Markdown by hand.
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
wowbagger --version # require 0.5.0-beta.0
|
|
81
|
+
wowbagger capabilities --json # require contract_version: 5
|
|
82
|
+
wowbagger validate --ledger ledger --json
|
|
83
|
+
wowbagger ready --ledger ledger --as-of YYYY-MM-DD --json
|
|
84
|
+
wowbagger inspect --ledger ledger --number N --json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For a write, inspect immediately before dispatch, send the returned exact-byte
|
|
88
|
+
revision as the compare-and-swap witness, use the explicit core mutation, and
|
|
89
|
+
validate again. On a provisioned ledger, commit each `create`, `transition`,
|
|
90
|
+
`parent-migrate`, `snooze`, `patch`, or `publish-claimed` mutation before the
|
|
91
|
+
next mutating command. Never replay a lost write: reconnect, re-read current
|
|
92
|
+
state, and treat the outcome as unknown until the core or a human resolves it.
|
|
93
|
+
Numbers are the human-facing item identity; `wb_...` ULIDs are internal
|
|
94
|
+
identities.
|
|
95
|
+
|
|
96
|
+
The core owns validation, ready selection, projections, lifecycle, CAS,
|
|
97
|
+
publication, claims, fencing, and reconciliation. The harness or host owns
|
|
98
|
+
dispatch, process safety, routing, and human approval. Claims coordinate
|
|
99
|
+
cooperating writers; they are not exclusive locks.
|
|
100
|
+
|
|
56
101
|
## Start here
|
|
57
102
|
|
|
58
|
-
Install the core CLI, then verify it
|
|
103
|
+
Install the core CLI, then verify it. The supported runtime is Node.js 24; Node
|
|
104
|
+
26 remains excluded because of the separate Vitest incompatibility:
|
|
59
105
|
|
|
60
106
|
```sh
|
|
61
|
-
npm install -g wowbagger@
|
|
107
|
+
npm install -g wowbagger@0.5.0-beta.0 # exact plugin-matched release
|
|
62
108
|
# or, from this release's Git tag:
|
|
63
|
-
# npm install -g github:lstutzman/wowbagger#v0.
|
|
64
|
-
wowbagger --version # 0.
|
|
65
|
-
wowbagger capabilities --json
|
|
109
|
+
# npm install -g github:lstutzman/wowbagger#v0.5.0-beta.0
|
|
110
|
+
wowbagger --version # 0.5.0-beta.0
|
|
111
|
+
wowbagger capabilities --json # must report contract_version: 5
|
|
66
112
|
```
|
|
67
113
|
|
|
68
|
-
In Claude Code,
|
|
114
|
+
In Claude Code, install the managed plugin:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
claude plugins install wowbagger
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Or, from inside a Claude Code session:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
/plugin install wowbagger
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This route is available after Wowbagger is listed in Claude Code's official
|
|
127
|
+
marketplace. Until then, or when installing a fork or unreleased revision, use
|
|
128
|
+
the direct repository marketplace:
|
|
69
129
|
|
|
70
130
|
```
|
|
71
131
|
/plugin marketplace add lstutzman/wowbagger
|
|
72
132
|
/plugin install wowbagger@wowbagger
|
|
73
133
|
```
|
|
74
134
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
135
|
+
For Codex and other agents, install the editable skill with `skills`:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
npx skills@latest add lstutzman/wowbagger --skill wowbagger
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Choose one route. Do not install both the managed Claude plugin and the
|
|
142
|
+
editable skill, or the skill will be loaded twice.
|
|
143
|
+
|
|
144
|
+
The plugin and `skills` installer drive the separately installed core rather
|
|
145
|
+
than bundling one, so a mismatch is detectable instead of silent. The skill
|
|
146
|
+
reads `wowbagger --version` and `capabilities`; it requires the same
|
|
147
|
+
distribution version as the plugin and core `contract_version: 5`. It refuses
|
|
148
|
+
an absent or incompatible core. It will not fall back to editing ledger files
|
|
149
|
+
by hand, because that would bypass validation and atomic publication.
|
|
150
|
+
|
|
151
|
+
Neither installer adds an MCP server, remote service, hook, or background
|
|
152
|
+
process. The plugin and skill operate on the ledger through the installed core.
|
|
81
153
|
|
|
82
154
|
### Set the ledger up before the first item
|
|
83
155
|
|
|
@@ -97,21 +169,45 @@ names — `create` publishes into an existing directory and does not make one.
|
|
|
97
169
|
Nothing is renamed after a create. This repository dogfoods that binding: its
|
|
98
170
|
own items live in [`ledger/items/`](ledger/items/).
|
|
99
171
|
|
|
100
|
-
If your items mirror an external tracker and carry
|
|
101
|
-
declare
|
|
102
|
-
|
|
172
|
+
If your items will mirror an external tracker and carry consumer-owned fields,
|
|
173
|
+
declare those fields **before the first item**. The declaration makes each
|
|
174
|
+
named extension member patchable:
|
|
103
175
|
|
|
104
176
|
```sh
|
|
105
177
|
echo '{"extensions_version":1,"members":{"external_id":"string"}}' \
|
|
106
178
|
> path/to/ledger/.wowbagger/extensions.json
|
|
107
179
|
```
|
|
108
180
|
|
|
109
|
-
Each member declares one value type
|
|
110
|
-
`string-list`.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
181
|
+
Each member declares one value type: `string`, `integer`, `boolean`, or
|
|
182
|
+
`string-list`. A ledger without the file has no patchable extension member,
|
|
183
|
+
and `set.extensions` refuses the missing declaration by name. The declaration
|
|
184
|
+
authorizes writes; it does not define item validity, so `validate` does not
|
|
185
|
+
read it. Commit the declaration with the other ledger setup.
|
|
186
|
+
|
|
187
|
+
If an existing ledger already carries extension values, do not create the
|
|
188
|
+
declaration by hand. Select every member and type explicitly in a request,
|
|
189
|
+
review a dry run, then publish the same proposal:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{"members":{"tags":"string-list"}}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
wowbagger extensions-provision --ledger path/to/ledger \
|
|
197
|
+
--input declaration.json --json --dry-run
|
|
198
|
+
wowbagger extensions-provision --ledger path/to/ledger \
|
|
199
|
+
--input declaration.json --json
|
|
200
|
+
git add path/to/ledger/.wowbagger/extensions.json
|
|
201
|
+
git commit -m "Declare patchable ledger extensions"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The command first requires a valid complete ledger. It validates every
|
|
205
|
+
occurrence of each selected member, reports occurrence counts, changes no item
|
|
206
|
+
bytes, and publishes one canonical declaration without overwriting a different
|
|
207
|
+
one. Commit that file before the first corresponding `patch`, inspect the
|
|
208
|
+
target for its current revision, then use `set.extensions.tags`. An item that
|
|
209
|
+
writes the selected member with a YAML anchor or alias remains
|
|
210
|
+
`extension-anchored` and requires a reviewed hand-edit.
|
|
115
211
|
|
|
116
212
|
Cores at `0.1.0-alpha.4` and earlier ignore the layout file and publish every
|
|
117
213
|
item at the ledger root.
|
|
@@ -200,8 +296,9 @@ skill exists because four things break when it does.
|
|
|
200
296
|
- **Validation is whole-ledger and fail-closed.** One malformed item refuses
|
|
201
297
|
every read and every guarded mutation on that ledger, including commands that
|
|
202
298
|
never touch it. A hand-edit finds that out later, and usually in someone
|
|
203
|
-
else's session. `create`, `transition`,
|
|
204
|
-
candidate ledger *before* publishing anything,
|
|
299
|
+
else's session. `create`, `transition`, `parent-migrate`, `snooze`, and
|
|
300
|
+
`patch` validate the complete candidate ledger *before* publishing anything,
|
|
301
|
+
and refuse `unchanged`.
|
|
205
302
|
- **A hand-edit has no lost-update guard.** Every guarded write takes the exact
|
|
206
303
|
SHA-256 revision `inspect` returned and refuses if the bytes moved. An editor
|
|
207
304
|
writes over whatever is there.
|
|
@@ -253,7 +350,7 @@ two supported install routes:
|
|
|
253
350
|
registry requires a `latest` tag), so a bare install resolves to the same
|
|
254
351
|
bytes.
|
|
255
352
|
- **git tag** —
|
|
256
|
-
`npm install -g github:lstutzman/wowbagger#v0.
|
|
353
|
+
`npm install -g github:lstutzman/wowbagger#v0.5.0-beta.0` installs this
|
|
257
354
|
release. Installing at a ref installs the core and every adapter that ref
|
|
258
355
|
carries.
|
|
259
356
|
|
|
@@ -289,10 +386,10 @@ version.
|
|
|
289
386
|
|
|
290
387
|
### Security
|
|
291
388
|
|
|
292
|
-
- **Read-only by default.** `validate`, `ready`, `report`, `inspect`,
|
|
293
|
-
`capabilities`, and `mint-id` never modify anything. Every mutation
|
|
294
|
-
(`create`, `transition`, `
|
|
295
|
-
reviewable write.
|
|
389
|
+
- **Read-only by default.** `validate`, `ready`, `report`, `inspect`, `list`,
|
|
390
|
+
`capabilities`, and `mint-id` never modify anything. Every item mutation
|
|
391
|
+
(`create`, `transition`, `parent-migrate`, `snooze`, `patch`, and
|
|
392
|
+
`publish-claimed`) is an explicit, reviewable write.
|
|
296
393
|
- **Lock is not a claim.** A short mutation lock serializes writers during one
|
|
297
394
|
operation. It does not grant a work claim.
|
|
298
395
|
- **Claims are merge-coordinated, not exclusive.** `claim acquire` uses
|
|
@@ -325,7 +422,7 @@ Upgrade the pieces you installed:
|
|
|
325
422
|
|
|
326
423
|
```sh
|
|
327
424
|
npm install -g wowbagger@next # public npm registry
|
|
328
|
-
npm install -g github:lstutzman/wowbagger#v0.
|
|
425
|
+
npm install -g github:lstutzman/wowbagger#v0.5.0-beta.0 # immutable Git release
|
|
329
426
|
git pull && npm ci # or: a direct checkout
|
|
330
427
|
```
|
|
331
428
|
|
|
@@ -373,6 +470,16 @@ core, these are the changes most likely to touch you:
|
|
|
373
470
|
`create` and refuses a caller-supplied one; `patch` refuses it because it is
|
|
374
471
|
immutable identity. Keep a legacy identifier in a declared extension member or
|
|
375
472
|
in the item body.
|
|
473
|
+
|
|
474
|
+
- **Repair duplicate numbers through `ledger-repair` version 1.** Generate a
|
|
475
|
+
read-only proposal with `number-repair-proposal`, review every
|
|
476
|
+
`expected_revision` and `replacement_number`, then apply the complete mapping
|
|
477
|
+
with `number-repair`. The command preserves ULID identities and relations and
|
|
478
|
+
does not change core contract version 5.
|
|
479
|
+
|
|
480
|
+
- **Run `version-drift --json` before mutation.** It compares the installed
|
|
481
|
+
skill pin, required core contract, and running core, and names the stale
|
|
482
|
+
package, plugin cache, or linked checkout with remediation.
|
|
376
483
|
- **Delete your local ULID generator.** `wowbagger mint-id --json` prints a
|
|
377
484
|
canonical ID; `--date YYYY-MM-DD` selects the creation date the ID must
|
|
378
485
|
encode.
|
|
@@ -483,7 +590,8 @@ approval never rides the bootstrap request, which the model controls;
|
|
|
483
590
|
|
|
484
591
|
## Core commands
|
|
485
592
|
|
|
486
|
-
The current core requires Node.js
|
|
593
|
+
The current core requires Node.js 24. Node 26 is not in the supported matrix.
|
|
594
|
+
From a Wowbagger checkout,
|
|
487
595
|
`./bin/wowbagger.js --help` prints the full command inventory,
|
|
488
596
|
`./bin/wowbagger.js <command> --help` prints that command's usage, and
|
|
489
597
|
`./bin/wowbagger.js --version` prints the installed package version. The
|
|
@@ -496,21 +604,28 @@ npm ci
|
|
|
496
604
|
./bin/wowbagger.js ready --ledger path/to/ledger --as-of 2030-01-15
|
|
497
605
|
./bin/wowbagger.js report --ledger path/to/ledger --as-of 2030-01-15 --json
|
|
498
606
|
./bin/wowbagger.js capabilities --json
|
|
499
|
-
./bin/wowbagger.js mint-id --json
|
|
500
607
|
./bin/wowbagger.js inspect --ledger path/to/ledger --id wb_... --json
|
|
501
608
|
./bin/wowbagger.js inspect --ledger path/to/ledger --number 30 --json
|
|
609
|
+
./bin/wowbagger.js list --ledger path/to/ledger --input query.json --json
|
|
502
610
|
./bin/wowbagger.js create --ledger path/to/ledger --input request.json --json
|
|
503
611
|
./bin/wowbagger.js transition --ledger path/to/ledger --input request.json --json
|
|
612
|
+
./bin/wowbagger.js parent-migrate --ledger path/to/ledger --input request.json --json
|
|
613
|
+
./bin/wowbagger.js snooze --ledger path/to/ledger --input request.json --json
|
|
504
614
|
./bin/wowbagger.js patch --ledger path/to/ledger --input request.json --json
|
|
615
|
+
./bin/wowbagger.js extensions-provision --ledger path/to/ledger --input declaration.json --json
|
|
616
|
+
./bin/wowbagger.js mint-id --json
|
|
617
|
+
./bin/wowbagger.js publish-claimed --ledger path/to/ledger --input request.json --json
|
|
618
|
+
./bin/wowbagger.js claim-merge-verify --ledger path/to/ledger --base main --head feature --json
|
|
619
|
+
./bin/wowbagger.js claim-sync --ledger path/to/ledger --json
|
|
620
|
+
./bin/wowbagger.js claim-adopt --ledger path/to/ledger --input request.json --json
|
|
621
|
+
./bin/wowbagger.js mutation-finalize --ledger path/to/ledger --recovery-token token --json
|
|
505
622
|
./bin/wowbagger.js provision --ledger path/to/ledger --json
|
|
506
623
|
./bin/wowbagger.js claim capabilities --ledger path/to/ledger --json
|
|
507
624
|
./bin/wowbagger.js claim acquire --ledger path/to/ledger --input request.json --json
|
|
508
625
|
./bin/wowbagger.js claim read --ledger path/to/ledger --input request.json --json
|
|
509
626
|
./bin/wowbagger.js claim renew --ledger path/to/ledger --input request.json --json
|
|
510
627
|
./bin/wowbagger.js claim release --ledger path/to/ledger --input request.json --json
|
|
511
|
-
./bin/wowbagger.js
|
|
512
|
-
./bin/wowbagger.js claim-verify --ledger path/to/ledger --json
|
|
513
|
-
./bin/wowbagger.js claim-adopt --ledger path/to/ledger --input request.json --json
|
|
628
|
+
./bin/wowbagger.js claim-verify --ledger path/to/ledger [--id wb_...] --json
|
|
514
629
|
```
|
|
515
630
|
|
|
516
631
|
`validate` writes exactly one JSON result to standard output. A valid ledger
|
|
@@ -573,10 +688,12 @@ change is an addition. And **extension members are patchable only where the
|
|
|
573
688
|
ledger declares them** — see [Set the ledger up before the first
|
|
574
689
|
item](#set-the-ledger-up-before-the-first-item).
|
|
575
690
|
|
|
576
|
-
Which members you own at all is a
|
|
577
|
-
consumer-editable through `patch`,
|
|
578
|
-
|
|
579
|
-
|
|
691
|
+
Which members you own at all is a four-way split — core-owned,
|
|
692
|
+
consumer-editable through `patch`, mutable through a dedicated command, and
|
|
693
|
+
create-once — stated member by member in the mutation contract's
|
|
694
|
+
**frontmatter ownership** table. Use `parent-migrate` to repoint an existing
|
|
695
|
+
item to or from an epic, and `snooze` to set or clear `snoozed_until`. Read the
|
|
696
|
+
table; do not send a patch and interpret the refusal.
|
|
580
697
|
|
|
581
698
|
### An epic's progress is derived, never stored
|
|
582
699
|
|
|
@@ -601,9 +718,11 @@ command asks you to parse the Markdown by hand:
|
|
|
601
718
|
refusal carries `error.details.item`, the complete snapshot of the item you
|
|
602
719
|
asked for, whenever no validation error names that item's path. A faulted
|
|
603
720
|
item is withheld; `validate` already names its repair.
|
|
604
|
-
- `claim-verify --json` reports `result.ledger_validation`.
|
|
605
|
-
|
|
606
|
-
|
|
721
|
+
- `claim-verify --json` reports `result.ledger_validation`. Bare verification
|
|
722
|
+
is strict repository-wide mode; `--id <item>` keeps all findings visible but
|
|
723
|
+
fails only for that item and global barriers. Exit 0 with an invalid
|
|
724
|
+
`ledger_validation` still means claim state is clean but validation blocks
|
|
725
|
+
mutation.
|
|
607
726
|
|
|
608
727
|
### Work claims
|
|
609
728
|
|
|
@@ -633,22 +752,29 @@ operating rule:
|
|
|
633
752
|
|
|
634
753
|
**Commit each mutation to Git before running the next mutating command.**
|
|
635
754
|
|
|
636
|
-
The durable claim store
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
`
|
|
755
|
+
The durable claim store reconciles every recorded mutation with Git `HEAD` and
|
|
756
|
+
the working tree. The next mutation refuses when that reconciliation finds an
|
|
757
|
+
`unauthorized-revision`, requires Git finalization, or requires synchronization
|
|
758
|
+
for the item the command targets. A synchronization finding on an unrelated
|
|
759
|
+
item remains visible to `claim-verify` but does not block the command.
|
|
760
|
+
|
|
761
|
+
An existing item's latest authorized working-tree bytes and an earlier
|
|
762
|
+
authorized revision at `HEAD` form an authorized predecessor/successor window.
|
|
763
|
+
That window produces no finding, so another mutation can run before the first
|
|
764
|
+
one is committed. Acceptance of the later mutation does not make either change
|
|
765
|
+
durable. Commit each mutation anyway, then run `claim-verify`.
|
|
641
766
|
|
|
642
767
|
The loop that works:
|
|
643
768
|
|
|
644
769
|
```sh
|
|
645
770
|
./bin/wowbagger.js create --ledger path/to/ledger --input request.json --json
|
|
646
771
|
git add path/to/ledger && git commit -m "Record the mutation"
|
|
647
|
-
./bin/wowbagger.js claim-verify --ledger path/to/ledger --json
|
|
772
|
+
./bin/wowbagger.js claim-verify --ledger path/to/ledger --id wb_... --json
|
|
648
773
|
./bin/wowbagger.js transition --ledger path/to/ledger --input next.json --json
|
|
649
774
|
```
|
|
650
775
|
|
|
651
|
-
|
|
776
|
+
For example, an authorized new item that is still absent from `HEAD` makes the
|
|
777
|
+
next command return exit 6:
|
|
652
778
|
|
|
653
779
|
```json
|
|
654
780
|
{"ok":false,"namespace":"ledger-mutation","command":"create-v1","contract_version":1,
|
|
@@ -663,10 +789,16 @@ Skip the commit and the next command returns exit 6:
|
|
|
663
789
|
`state: "unchanged"` is exact — nothing was written. **`claim-verify` is the
|
|
664
790
|
reconciliation procedure.** Read `details.findings`, do what each
|
|
665
791
|
`remediation` string says, run `claim-verify` until it returns exit 0, then
|
|
666
|
-
repeat the refused command.
|
|
792
|
+
repeat the refused command. A `worktree-synchronization-required` finding on an
|
|
793
|
+
unrelated item does not block the requested mutation. The same finding on the
|
|
794
|
+
target item, and every `unauthorized-revision` finding, remains blocking.
|
|
667
795
|
|
|
668
|
-
Batch work is where this bites. Filing ten items means ten
|
|
669
|
-
commit
|
|
796
|
+
Batch work is where this bites. Filing ten items means ten serial
|
|
797
|
+
`create --auto-commit` calls and ten commits, not one batch commit. Wowbagger
|
|
798
|
+
permanently rejects batch create for the direct-Markdown architecture:
|
|
799
|
+
`limits.multi_item_atomicity` remains `false`, request order is the supported
|
|
800
|
+
bulk order, and each create must finish or recover before the next begins. See
|
|
801
|
+
the [batch-create decision](docs/design/2026-08-30-batch-create.md).
|
|
670
802
|
|
|
671
803
|
### Or fold the commit into the mutation
|
|
672
804
|
|
|
@@ -679,16 +811,23 @@ ledger only:
|
|
|
679
811
|
|
|
680
812
|
It is opt-in per invocation. There is no configuration setting or environment
|
|
681
813
|
default, because a hidden default would make existing automation create Git
|
|
682
|
-
commits unexpectedly. The flag is accepted on `create`, `transition`,
|
|
683
|
-
and `publish-claimed`.
|
|
814
|
+
commits unexpectedly. The flag is accepted on `create`, `transition`,
|
|
815
|
+
`parent-migrate`, `snooze`, `patch`, and `publish-claimed`.
|
|
684
816
|
|
|
685
817
|
What one flagged invocation does: refuse if anything is staged anywhere or any
|
|
686
|
-
path under the ledger is dirty; reconcile; run the mutation unchanged;
|
|
687
|
-
exactly the changed item and at most one
|
|
818
|
+
foreign path under the ledger is dirty; reconcile; run the mutation unchanged;
|
|
819
|
+
commit exactly the changed item and at most one
|
|
688
820
|
`.wowbagger/reconcile-<namespace>.md` with a fixed subject such as
|
|
689
821
|
`wowbagger: transition item #7`; verify the commit; then run `claim-verify`
|
|
690
|
-
before it answers.
|
|
691
|
-
`
|
|
822
|
+
before it answers. A command that owns the claim journal may rebuild only its
|
|
823
|
+
derived reconciliation log during preflight. `create` remains strict, and
|
|
824
|
+
every other dirty ledger path still refuses. On success the result gains
|
|
825
|
+
`git_commit`, `commit_paths`, and `claim_verified`.
|
|
826
|
+
|
|
827
|
+
If claim verification refuses, auto-commit preserves its code and reason in
|
|
828
|
+
`claim_verify_code` and `claim_verify_reason`. Only
|
|
829
|
+
`claim_verify_reason: "claim-store-locked"` is retryable; unresolved
|
|
830
|
+
reconciliation is not.
|
|
692
831
|
|
|
693
832
|
Unstaged and untracked files **outside** the ledger are left alone. Hooks and
|
|
694
833
|
signing are honoured; `--no-verify` is never passed. Nothing is pushed.
|
|
@@ -1074,18 +1213,20 @@ the finding as a ledger item rather than leaving it in a transcript.
|
|
|
1074
1213
|
|
|
1075
1214
|
### The verification gate
|
|
1076
1215
|
|
|
1077
|
-
Four commands. All four must pass, and the test commands run on **
|
|
1078
|
-
current Node runtime and Node 20:
|
|
1216
|
+
Four commands. All four must pass, and the test commands run on **Node 24.20.0**:
|
|
1079
1217
|
|
|
1080
1218
|
```sh
|
|
1081
|
-
TMPDIR=/tmp node --test test/*.test.js
|
|
1082
|
-
TMPDIR=/tmp /opt/homebrew/opt/node@
|
|
1083
|
-
TMPDIR=/tmp node spec/run-adapter-implementation.js
|
|
1084
|
-
node bin/wowbagger.js validate --ledger ledger --json
|
|
1219
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node --test test/*.test.js
|
|
1220
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node --pending-deprecation --throw-deprecation --test test/*.test.js
|
|
1221
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node spec/run-adapter-implementation.js
|
|
1222
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node bin/wowbagger.js validate --ledger ledger --json
|
|
1085
1223
|
```
|
|
1086
1224
|
|
|
1087
1225
|
`TMPDIR=/tmp` is not optional: the default macOS temporary path makes the claim
|
|
1088
|
-
lock socket path too long.
|
|
1226
|
+
lock socket path too long. Use an explicit Node 24.20.0 binary path.
|
|
1227
|
+
|
|
1228
|
+
The supported runtime matrix is Node 24.20.0. Node 26 remains excluded until
|
|
1229
|
+
the separate Vitest incompatibility reported by Lee is resolved.
|
|
1089
1230
|
|
|
1090
1231
|
`npm test`, `npm audit --omit=dev`, and `git diff --check` are useful alongside
|
|
1091
1232
|
it; they are not a substitute for the four commands above.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/adapter-contract.md
CHANGED
|
@@ -1477,7 +1477,7 @@ error registry. It changes only this versioned surface:
|
|
|
1477
1477
|
The core capability probe adapter contract version 2 requires is core
|
|
1478
1478
|
contract version 5. It adds exactly
|
|
1479
1479
|
`operations.patch: {"supported":true,"write_scope":"single-item","cas_scope":"exact-byte-sha256"}`,
|
|
1480
|
-
`operations.work_claim.api_version:
|
|
1480
|
+
`operations.work_claim.api_version: 3`, and
|
|
1481
1481
|
`limits.max_item_source_bytes: 8388608` as the first member of
|
|
1482
1482
|
`limits`.
|
|
1483
1483
|
Its mutation backend scope is always
|
package/docs/host-contract.md
CHANGED
|
@@ -26,10 +26,13 @@ shell: an absolute Node executable, the absolute `wowbagger.js` the package
|
|
|
26
26
|
installed, an argument array, and `shell: false`. Neither path is discovered by
|
|
27
27
|
searching a global npm directory, and neither is a platform command shim.
|
|
28
28
|
|
|
29
|
-
Wowbagger requires Node.js
|
|
29
|
+
Wowbagger requires Node.js 24 or later. The package declares that floor in
|
|
30
30
|
`engines.node`, and the launch seam exports it as `MINIMUM_NODE_MAJOR` for a
|
|
31
31
|
host that resolves its own runtime instead of reusing the one it is running on.
|
|
32
32
|
|
|
33
|
+
The supported release matrix is Node 24.20.0. Node 26 is excluded until the
|
|
34
|
+
separate Vitest incompatibility reported by Lee is resolved.
|
|
35
|
+
|
|
33
36
|
~~~js
|
|
34
37
|
import { resolveCoreLaunch } from 'wowbagger';
|
|
35
38
|
|
|
@@ -258,6 +261,9 @@ not a fetch URL.
|
|
|
258
261
|
| `bare-ready-result.json` | bare result | a `ready` success |
|
|
259
262
|
| `ledger-mutation-refusal.json` | ledger-mutation 1 | the legacy-write fence refusals |
|
|
260
263
|
| `report-config-v1.json` | report config 1 | `<ledger>/.wowbagger/report.json` at version 1 |
|
|
264
|
+
| `ledger-repair-request.json` | ledger-repair 1 | the strict `number-repair` request |
|
|
265
|
+
| `ledger-repair-proposal.json` | ledger-repair 1 | the read-only `number-repair-proposal` result |
|
|
266
|
+
| `ledger-repair-response.json` | ledger-repair 1 | every `number-repair-proposal` and `number-repair` response |
|
|
261
267
|
| `report-config-v2.json` | report config 2 | the same file at version 2, which names views |
|
|
262
268
|
|
|
263
269
|
Every schema fixes its root members exactly and pins the version of its own
|