wowbagger 0.1.0-alpha.14 → 0.1.0-alpha.17
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 +49 -0
- package/README.md +27 -15
- package/docs/host-contract.md +7 -1
- package/docs/mutation-contract.md +14 -5
- package/docs/work-claim-contract.md +8 -10
- package/package.json +2 -2
- 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 +27 -10
- package/src/claim-journal.js +81 -0
- package/src/claim-request.js +9 -0
- package/src/cli.js +122 -29
- package/src/launch.js +2 -2
- package/src/ledger-repair.js +1170 -0
- package/src/version-drift.js +98 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,55 @@ consolidation. The first tagged release inherits this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.1.0-alpha.17 - 2026-08-30
|
|
11
|
+
|
|
12
|
+
- **Breaking:** raise the supported Node.js floor from 20 to 24. Node 20 and
|
|
13
|
+
Node 22 no longer satisfy `engines.node`; Node 26 remains outside the
|
|
14
|
+
supported matrix because of the separate Vitest incompatibility reported by
|
|
15
|
+
Lee.
|
|
16
|
+
|
|
17
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
18
|
+
answers **The durable claim store is unavailable.** with
|
|
19
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14 create.
|
|
20
|
+
There is no automatic migration or mixed-version grace period. There is no
|
|
21
|
+
batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
22
|
+
batch design, and item #182 owns existing duplicate numbers. The fence adds no
|
|
23
|
+
new Git roster or history traversal and costs two extra fsync'd journal appends
|
|
24
|
+
within the 65,536-entry limit.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## 0.1.0-alpha.16 - 2026-08-30
|
|
28
|
+
|
|
29
|
+
- Added `version-drift --json` to detect stale installed skill pins, core
|
|
30
|
+
contract versions, and package provenance before ledger mutation.
|
|
31
|
+
|
|
32
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
33
|
+
answers **The durable claim store is unavailable.** with
|
|
34
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14
|
|
35
|
+
create. There is no automatic migration or mixed-version grace period. There is
|
|
36
|
+
no batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
37
|
+
batch design, and item #182 owns existing duplicate numbers. The fence adds no
|
|
38
|
+
new Git roster or history traversal and costs two extra fsync'd journal appends
|
|
39
|
+
within the 65,536-entry limit.
|
|
40
|
+
|
|
41
|
+
## 0.1.0-alpha.15 - 2026-08-30
|
|
42
|
+
|
|
43
|
+
- **Duplicate-number recovery now has a separate `ledger-repair` contract
|
|
44
|
+
version 1.** Use the read-only `number-repair-proposal` command to review a
|
|
45
|
+
complete mapping, then apply it with `number-repair`. The repair path requires
|
|
46
|
+
duplicate-number errors to be the complete validation failure, preserves ULID
|
|
47
|
+
identities and relation values, uses the shared namespace fence, records
|
|
48
|
+
durable intent/final entries, and supports bounded auto-commit recovery.
|
|
49
|
+
|
|
50
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
51
|
+
answers **The durable claim store is unavailable.** with
|
|
52
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14
|
|
53
|
+
create. There is no automatic migration or mixed-version grace period. There is
|
|
54
|
+
no batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
55
|
+
batch design, and item #182 owns existing duplicate numbers.
|
|
56
|
+
The fence adds no new Git roster or history traversal and costs two extra
|
|
57
|
+
fsync'd journal appends within the 65,536-entry limit.
|
|
58
|
+
|
|
10
59
|
## 0.1.0-alpha.14 - 2026-08-29
|
|
11
60
|
|
|
12
61
|
### Changed
|
package/README.md
CHANGED
|
@@ -30,8 +30,8 @@ agent to use those guarantees instead of hand-editing your Markdown.
|
|
|
30
30
|
|
|
31
31
|
**Start here:** [install the core and set up a ledger](#start-here).
|
|
32
32
|
|
|
33
|
-
> **Status: alpha, published, and self-hosted.** `0.1.0-alpha.
|
|
34
|
-
> the `next` tag and on this repository's `v0.1.0-alpha.
|
|
33
|
+
> **Status: alpha, published, and self-hosted.** `0.1.0-alpha.17` is on npm under
|
|
34
|
+
> the `next` tag and on this repository's `v0.1.0-alpha.17` tag. It is the
|
|
35
35
|
> version this repository runs its own backlog on. The API is not frozen and the
|
|
36
36
|
> version will move before a stable release.
|
|
37
37
|
>
|
|
@@ -77,7 +77,7 @@ Wowbagger is the core authority for a Git-native work ledger. Use it instead
|
|
|
77
77
|
of editing ledger Markdown by hand.
|
|
78
78
|
|
|
79
79
|
```sh
|
|
80
|
-
wowbagger --version # require 0.1.0-alpha.
|
|
80
|
+
wowbagger --version # require 0.1.0-alpha.17
|
|
81
81
|
wowbagger capabilities --json # require contract_version: 5
|
|
82
82
|
wowbagger validate --ledger ledger --json
|
|
83
83
|
wowbagger ready --ledger ledger --as-of YYYY-MM-DD --json
|
|
@@ -103,10 +103,10 @@ cooperating writers; they are not exclusive locks.
|
|
|
103
103
|
Install the core CLI, then verify it. The core requires Node.js 20 or later:
|
|
104
104
|
|
|
105
105
|
```sh
|
|
106
|
-
npm install -g wowbagger@0.1.0-alpha.
|
|
106
|
+
npm install -g wowbagger@0.1.0-alpha.17 # exact plugin-matched release
|
|
107
107
|
# or, from this release's Git tag:
|
|
108
|
-
# npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.
|
|
109
|
-
wowbagger --version # 0.1.0-alpha.
|
|
108
|
+
# npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.17
|
|
109
|
+
wowbagger --version # 0.1.0-alpha.17
|
|
110
110
|
wowbagger capabilities --json # must report contract_version: 5
|
|
111
111
|
```
|
|
112
112
|
|
|
@@ -325,7 +325,7 @@ two supported install routes:
|
|
|
325
325
|
registry requires a `latest` tag), so a bare install resolves to the same
|
|
326
326
|
bytes.
|
|
327
327
|
- **git tag** —
|
|
328
|
-
`npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.
|
|
328
|
+
`npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.17` installs this
|
|
329
329
|
release. Installing at a ref installs the core and every adapter that ref
|
|
330
330
|
carries.
|
|
331
331
|
|
|
@@ -397,7 +397,7 @@ Upgrade the pieces you installed:
|
|
|
397
397
|
|
|
398
398
|
```sh
|
|
399
399
|
npm install -g wowbagger@next # public npm registry
|
|
400
|
-
npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.
|
|
400
|
+
npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.17 # immutable Git release
|
|
401
401
|
git pull && npm ci # or: a direct checkout
|
|
402
402
|
```
|
|
403
403
|
|
|
@@ -445,6 +445,16 @@ core, these are the changes most likely to touch you:
|
|
|
445
445
|
`create` and refuses a caller-supplied one; `patch` refuses it because it is
|
|
446
446
|
immutable identity. Keep a legacy identifier in a declared extension member or
|
|
447
447
|
in the item body.
|
|
448
|
+
|
|
449
|
+
- **Repair duplicate numbers through `ledger-repair` version 1.** Generate a
|
|
450
|
+
read-only proposal with `number-repair-proposal`, review every
|
|
451
|
+
`expected_revision` and `replacement_number`, then apply the complete mapping
|
|
452
|
+
with `number-repair`. The command preserves ULID identities and relations and
|
|
453
|
+
does not change core contract version 5.
|
|
454
|
+
|
|
455
|
+
- **Run `version-drift --json` before mutation.** It compares the installed
|
|
456
|
+
skill pin, required core contract, and running core, and names the stale
|
|
457
|
+
package, plugin cache, or linked checkout with remediation.
|
|
448
458
|
- **Delete your local ULID generator.** `wowbagger mint-id --json` prints a
|
|
449
459
|
canonical ID; `--date YYYY-MM-DD` selects the creation date the ID must
|
|
450
460
|
encode.
|
|
@@ -1171,18 +1181,20 @@ the finding as a ledger item rather than leaving it in a transcript.
|
|
|
1171
1181
|
|
|
1172
1182
|
### The verification gate
|
|
1173
1183
|
|
|
1174
|
-
Four commands. All four must pass, and the test commands run on **
|
|
1175
|
-
current Node runtime and Node 20:
|
|
1184
|
+
Four commands. All four must pass, and the test commands run on **Node 24.20.0**:
|
|
1176
1185
|
|
|
1177
1186
|
```sh
|
|
1178
|
-
TMPDIR=/tmp node --test test/*.test.js
|
|
1179
|
-
TMPDIR=/tmp /opt/homebrew/opt/node@
|
|
1180
|
-
TMPDIR=/tmp node spec/run-adapter-implementation.js
|
|
1181
|
-
node bin/wowbagger.js validate --ledger ledger --json
|
|
1187
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node --test test/*.test.js
|
|
1188
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node --pending-deprecation --throw-deprecation --test test/*.test.js
|
|
1189
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node spec/run-adapter-implementation.js
|
|
1190
|
+
TMPDIR=/tmp /opt/homebrew/opt/node@24/bin/node bin/wowbagger.js validate --ledger ledger --json
|
|
1182
1191
|
```
|
|
1183
1192
|
|
|
1184
1193
|
`TMPDIR=/tmp` is not optional: the default macOS temporary path makes the claim
|
|
1185
|
-
lock socket path too long.
|
|
1194
|
+
lock socket path too long. Use an explicit Node 24.20.0 binary path.
|
|
1195
|
+
|
|
1196
|
+
The supported runtime matrix is Node 24.20.0. Node 26 remains excluded until
|
|
1197
|
+
the separate Vitest incompatibility reported by Lee is resolved.
|
|
1186
1198
|
|
|
1187
1199
|
`npm test`, `npm audit --omit=dev`, and `git diff --check` are useful alongside
|
|
1188
1200
|
it; they are not a substitute for the four commands above.
|
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
|
|
@@ -376,6 +376,7 @@ answer in two domains.
|
|
|
376
376
|
| work-claim | `work-claim` | 1, the legacy envelope marker | `result.operations.work_claim.api_version` of `claim capabilities --json` |
|
|
377
377
|
| ledger-publication | `ledger-publication` | 1, the legacy envelope marker | the same work-claim `api_version` |
|
|
378
378
|
| ledger-mutation | `ledger-mutation` | 1, the legacy envelope marker | the same work-claim `api_version` |
|
|
379
|
+
| ledger-repair | `ledger-repair` | 1 | `contract_version` of `number-repair-proposal` or `number-repair` |
|
|
379
380
|
| bare result | absent, and no `ok` member either | none | none |
|
|
380
381
|
|
|
381
382
|
The rule has three steps:
|
|
@@ -401,6 +402,7 @@ legacy claim-envelope marker, and a consumer must never compare it with the core
|
|
|
401
402
|
| `inspect` | core | core |
|
|
402
403
|
| `list` | core | core |
|
|
403
404
|
| `mint-id` | core | core |
|
|
405
|
+
| `version-drift` | core | core |
|
|
404
406
|
| `report` | core | core |
|
|
405
407
|
| `create` | core | core, or ledger-mutation when the claim fence refuses |
|
|
406
408
|
| `transition` | core | core, or ledger-mutation when the claim fence refuses |
|
|
@@ -415,7 +417,8 @@ legacy claim-envelope marker, and a consumer must never compare it with the core
|
|
|
415
417
|
| `claim-sync` | work-claim | work-claim |
|
|
416
418
|
| `claim-adopt` | work-claim | work-claim |
|
|
417
419
|
| `mutation-finalize` | work-claim | work-claim |
|
|
418
|
-
| `
|
|
420
|
+
| `number-repair-proposal` | ledger-repair | ledger-repair |
|
|
421
|
+
| `number-repair` | ledger-repair | ledger-repair |
|
|
419
422
|
| `publish-claimed` | ledger-publication | ledger-publication |
|
|
420
423
|
|
|
421
424
|
**Exact root members**
|
|
@@ -1600,10 +1603,16 @@ A create has no authorized predecessor, so Git `HEAD` is the only surface that
|
|
|
1600
1603
|
can carry its authorized bytes, and an uncommitted create raises the global
|
|
1601
1604
|
`git-finalization-required` barrier for every later mutation. Commit each
|
|
1602
1605
|
created item before the next mutating command. This release adds no batch
|
|
1603
|
-
mutation; the supported bulk pattern
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1606
|
+
mutation; the supported bulk pattern remains the create-then-commit loop.
|
|
1607
|
+
A ledger that already carries duplicate numbers is item #182 recovery work and
|
|
1608
|
+
is repaired through the separate `ledger-repair` contract, not through core
|
|
1609
|
+
version 5 mutation. Run
|
|
1610
|
+
`number-repair-proposal --ledger <dir> --json`, review the complete mapping, then
|
|
1611
|
+
run `number-repair --ledger <dir> --input <repair.json> --json`. The repair
|
|
1612
|
+
command operates only when duplicate-number errors are the complete validation
|
|
1613
|
+
failure, preserves ULID identities and relation values, and publishes all
|
|
1614
|
+
affected items under the shared namespace fence. Arbitrary hand edits remain
|
|
1615
|
+
unsupported because they can damage IDs, paths, or references.
|
|
1607
1616
|
|
|
1608
1617
|
**What this guarantees, and what it does not.** The fence closes the reported
|
|
1609
1618
|
PropertyCompass2 collision: cooperating alpha.14 worktrees of one clone that
|
|
@@ -477,16 +477,14 @@ intent and one committed terminal, so with no other activity the
|
|
|
477
477
|
ceiling. Capacity is checked before publication and fails closed. Journal
|
|
478
478
|
compaction is not part of this change.
|
|
479
479
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
reference checks every mutation performs, so it can leave dangling
|
|
489
|
-
`depends_on`, `related`, and parent references that nothing reports.
|
|
480
|
+
A ledger that already carries duplicate numbers is item #182 recovery work and
|
|
481
|
+
is repaired through the separate `ledger-repair` contract, not through claim
|
|
482
|
+
operations. Run `number-repair-proposal --ledger <dir> --json`, review the
|
|
483
|
+
complete mapping, then run `number-repair --ledger <dir> --input <repair.json>
|
|
484
|
+
--json`. The repair command runs only when duplicate-number errors are the
|
|
485
|
+
complete validation failure, preserves ULID identities and relation values, and
|
|
486
|
+
publishes all affected items under the shared namespace fence. Arbitrary hand
|
|
487
|
+
edits remain unsupported because they can damage IDs, paths, or references.
|
|
490
488
|
|
|
491
489
|
**What alpha.14 guarantees, and what it does not.** Alpha.14 closes the
|
|
492
490
|
reported PropertyCompass2 collision: cooperating alpha.14 worktrees of one
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wowbagger",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.17",
|
|
4
4
|
"description": "Git-native work ledger for coding agents: deterministic ready queues, guarded CAS mutations, claims and fencing, and self-contained HTML reports.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"cli"
|
|
31
31
|
],
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": ">=
|
|
33
|
+
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"bin": {
|
|
36
36
|
"wowbagger": "bin/wowbagger.js"
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"inspect",
|
|
26
26
|
"list",
|
|
27
27
|
"mint-id",
|
|
28
|
-
"report"
|
|
28
|
+
"report",
|
|
29
|
+
"version-drift"
|
|
29
30
|
]
|
|
30
31
|
},
|
|
31
32
|
"contract_version": {
|
|
@@ -55,8 +56,8 @@
|
|
|
55
56
|
"capabilities",
|
|
56
57
|
"inspect",
|
|
57
58
|
"list",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
59
|
+
"report",
|
|
60
|
+
"version-drift"
|
|
60
61
|
]
|
|
61
62
|
},
|
|
62
63
|
"contract_version": {
|
package/schemas/index.json
CHANGED
|
@@ -92,6 +92,24 @@
|
|
|
92
92
|
"version": 1,
|
|
93
93
|
"summary": "Legacy-write fence refusals in the ledger-mutation namespace."
|
|
94
94
|
},
|
|
95
|
+
{
|
|
96
|
+
"file": "ledger-repair-proposal.json",
|
|
97
|
+
"domain": "ledger-repair",
|
|
98
|
+
"version": 1,
|
|
99
|
+
"summary": "The read-only duplicate-number repair proposal result."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"file": "ledger-repair-request.json",
|
|
103
|
+
"domain": "ledger-repair",
|
|
104
|
+
"version": 1,
|
|
105
|
+
"summary": "The strict number-repair request, covering the complete duplicate set."
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"file": "ledger-repair-response.json",
|
|
109
|
+
"domain": "ledger-repair",
|
|
110
|
+
"version": 1,
|
|
111
|
+
"summary": "Every ledger-repair response: the proposal and apply envelopes at repair version 1."
|
|
112
|
+
},
|
|
95
113
|
{
|
|
96
114
|
"file": "report-config-v1.json",
|
|
97
115
|
"domain": "report-config",
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/lstutzman/wowbagger/schemas/ledger-repair-proposal.json",
|
|
4
|
+
"title": "number-repair-proposal result, ledger-repair version 1",
|
|
5
|
+
"description": "The `result` member of a successful `number-repair-proposal` response. The proposal is read-only: it reads the raw items of a ledger whose complete error set is duplicate numbers and computes the mapping that would repair it, writing nothing. The caller confirms or replaces `suggested_changes` and submits them as a `number-repair` request, which validates every witness again under the repair lock.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"ledger_snapshot_revision",
|
|
10
|
+
"duplicate_groups",
|
|
11
|
+
"items",
|
|
12
|
+
"suggested_changes",
|
|
13
|
+
"preserved_items",
|
|
14
|
+
"validation_errors"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"ledger_snapshot_revision": {
|
|
18
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/revision",
|
|
19
|
+
"description": "The digest over the complete relevant source bytes this proposal was computed from. A repair request replays it so a changed ledger is a conflict rather than a surprise."
|
|
20
|
+
},
|
|
21
|
+
"duplicate_groups": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"minItems": 1,
|
|
24
|
+
"description": "One entry per duplicated number, naming every item that carries it. A repair request must resolve every group.",
|
|
25
|
+
"items": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"required": [
|
|
29
|
+
"number",
|
|
30
|
+
"item_ids"
|
|
31
|
+
],
|
|
32
|
+
"properties": {
|
|
33
|
+
"number": {
|
|
34
|
+
"type": "integer",
|
|
35
|
+
"minimum": 1
|
|
36
|
+
},
|
|
37
|
+
"item_ids": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"minItems": 2,
|
|
40
|
+
"uniqueItems": true,
|
|
41
|
+
"items": {
|
|
42
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"minItems": 1,
|
|
51
|
+
"description": "Every item in a duplicate group, with the configured path and exact source revision a repair request witnesses.",
|
|
52
|
+
"items": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": [
|
|
56
|
+
"item_id",
|
|
57
|
+
"path",
|
|
58
|
+
"revision",
|
|
59
|
+
"number"
|
|
60
|
+
],
|
|
61
|
+
"properties": {
|
|
62
|
+
"item_id": {
|
|
63
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
64
|
+
},
|
|
65
|
+
"path": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1,
|
|
68
|
+
"description": "The item's configured path, relative to the ledger directory."
|
|
69
|
+
},
|
|
70
|
+
"revision": {
|
|
71
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/revision"
|
|
72
|
+
},
|
|
73
|
+
"number": {
|
|
74
|
+
"type": "integer",
|
|
75
|
+
"minimum": 1
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"suggested_changes": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"minItems": 1,
|
|
83
|
+
"description": "The computed mapping, in the exact shape of the `changes` member of a number-repair request. Each group keeps the number on its lexicographically smallest ULID and moves the rest above the current maximum number.",
|
|
84
|
+
"items": {
|
|
85
|
+
"type": "object",
|
|
86
|
+
"additionalProperties": false,
|
|
87
|
+
"required": [
|
|
88
|
+
"item_id",
|
|
89
|
+
"expected_revision",
|
|
90
|
+
"expected_number",
|
|
91
|
+
"replacement_number"
|
|
92
|
+
],
|
|
93
|
+
"properties": {
|
|
94
|
+
"item_id": {
|
|
95
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
96
|
+
},
|
|
97
|
+
"expected_revision": {
|
|
98
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/revision"
|
|
99
|
+
},
|
|
100
|
+
"expected_number": {
|
|
101
|
+
"type": "integer",
|
|
102
|
+
"minimum": 1
|
|
103
|
+
},
|
|
104
|
+
"replacement_number": {
|
|
105
|
+
"type": "integer",
|
|
106
|
+
"minimum": 1
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"preserved_items": {
|
|
112
|
+
"type": "array",
|
|
113
|
+
"minItems": 1,
|
|
114
|
+
"description": "Item IDs the proposal keeps at their current number.",
|
|
115
|
+
"uniqueItems": true,
|
|
116
|
+
"items": {
|
|
117
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"references": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"description": "The affected items' relations, exactly as the source carries them. Relations are ULIDs, so a number repair preserves them; they are reported so a caller can confirm that nothing identity-bearing is being rewritten.",
|
|
123
|
+
"items": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"additionalProperties": false,
|
|
126
|
+
"required": [
|
|
127
|
+
"item_id",
|
|
128
|
+
"depends_on",
|
|
129
|
+
"related",
|
|
130
|
+
"parent"
|
|
131
|
+
],
|
|
132
|
+
"properties": {
|
|
133
|
+
"item_id": {
|
|
134
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
135
|
+
},
|
|
136
|
+
"depends_on": {
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": {
|
|
139
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"related": {
|
|
143
|
+
"type": "array",
|
|
144
|
+
"items": {
|
|
145
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"parent": {
|
|
149
|
+
"oneOf": [
|
|
150
|
+
{
|
|
151
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"type": "null"
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"validation_errors": {
|
|
162
|
+
"type": "array",
|
|
163
|
+
"minItems": 1,
|
|
164
|
+
"description": "The complete current validation errors. A proposal is produced only when every one of them is a duplicate-number error; any other error returns ledger-repair-not-applicable instead.",
|
|
165
|
+
"items": {
|
|
166
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/validationError"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/lstutzman/wowbagger/schemas/ledger-repair-request.json",
|
|
4
|
+
"title": "number-repair request, ledger-repair version 1",
|
|
5
|
+
"description": "The strict JSON request `number-repair` reads from stdin or a host-created request file. One request covers the complete duplicate set: a partial mapping is refused, because moving one group cannot produce a valid complete ledger while another group remains. Each change carries the witnesses the apply path compares under the repair lock. `ledger-repair` is its own contract version, separate from the core contract version and the work-claim contract version.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"repair_id",
|
|
10
|
+
"ledger_snapshot_revision",
|
|
11
|
+
"date",
|
|
12
|
+
"changes"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"repair_id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^nr_[0-9]{8}_[0-9]{4}$",
|
|
18
|
+
"description": "The bounded recovery key: `nr_`, the repair date, and a four-digit sequence within that date. An interrupted apply is resumed by this ID rather than retried blindly."
|
|
19
|
+
},
|
|
20
|
+
"ledger_snapshot_revision": {
|
|
21
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/revision",
|
|
22
|
+
"description": "The complete-snapshot witness the proposal was computed against. A changed snapshot is a conflict, never a repair applied to bytes the caller never read."
|
|
23
|
+
},
|
|
24
|
+
"date": {
|
|
25
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/isoDate"
|
|
26
|
+
},
|
|
27
|
+
"changes": {
|
|
28
|
+
"type": "array",
|
|
29
|
+
"minItems": 1,
|
|
30
|
+
"description": "One entry per moved item. No `item_id` repeats, because an item moves once, and no `replacement_number` repeats, because two items cannot land on one number. An empty list is an invalid request rather than a no-op.",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": [
|
|
35
|
+
"item_id",
|
|
36
|
+
"expected_revision",
|
|
37
|
+
"expected_number",
|
|
38
|
+
"replacement_number"
|
|
39
|
+
],
|
|
40
|
+
"properties": {
|
|
41
|
+
"item_id": {
|
|
42
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/itemId"
|
|
43
|
+
},
|
|
44
|
+
"expected_revision": {
|
|
45
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/revision"
|
|
46
|
+
},
|
|
47
|
+
"expected_number": {
|
|
48
|
+
"type": "integer",
|
|
49
|
+
"minimum": 1,
|
|
50
|
+
"description": "The number the item carries now, compared as an integer. It is a witness, not a label."
|
|
51
|
+
},
|
|
52
|
+
"replacement_number": {
|
|
53
|
+
"type": "integer",
|
|
54
|
+
"minimum": 1,
|
|
55
|
+
"description": "The number the item is moved to. The apply path refuses a collision with any item that is not being moved."
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/lstutzman/wowbagger/schemas/ledger-repair-response.json",
|
|
4
|
+
"title": "ledger-repair responses, contract version 1",
|
|
5
|
+
"description": "Every `number-repair-proposal` and `number-repair` --json response. The root carries a `namespace` member: dispatch on `namespace` before reading any version field. `contract_version` is the repair domain's own version 1 — the core contract version and the work-claim contract version are separate and unchanged by it. A future change to the request or the repaired source shape requires a new repair contract version rather than a silent reinterpretation of version 1.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"oneOf": [
|
|
8
|
+
{
|
|
9
|
+
"title": "repair success",
|
|
10
|
+
"type": "object",
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"required": [
|
|
13
|
+
"ok",
|
|
14
|
+
"namespace",
|
|
15
|
+
"command",
|
|
16
|
+
"contract_version",
|
|
17
|
+
"state",
|
|
18
|
+
"result"
|
|
19
|
+
],
|
|
20
|
+
"properties": {
|
|
21
|
+
"ok": {
|
|
22
|
+
"const": true
|
|
23
|
+
},
|
|
24
|
+
"namespace": {
|
|
25
|
+
"const": "ledger-repair"
|
|
26
|
+
},
|
|
27
|
+
"command": {
|
|
28
|
+
"enum": [
|
|
29
|
+
"number-repair-proposal",
|
|
30
|
+
"number-repair"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"contract_version": {
|
|
34
|
+
"const": 1
|
|
35
|
+
},
|
|
36
|
+
"state": {
|
|
37
|
+
"enum": [
|
|
38
|
+
"unchanged",
|
|
39
|
+
"committed"
|
|
40
|
+
],
|
|
41
|
+
"description": "A proposal changes nothing, so it is always `unchanged`. An applied repair is `committed`."
|
|
42
|
+
},
|
|
43
|
+
"result": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"description": "The proposal result is the ledger-repair-proposal schema. The apply result names the repair ID, the snapshot it was applied against, the changed items, and the Git commit when one was established."
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"title": "repair refusal",
|
|
51
|
+
"type": "object",
|
|
52
|
+
"additionalProperties": false,
|
|
53
|
+
"required": [
|
|
54
|
+
"ok",
|
|
55
|
+
"namespace",
|
|
56
|
+
"command",
|
|
57
|
+
"contract_version",
|
|
58
|
+
"state",
|
|
59
|
+
"error"
|
|
60
|
+
],
|
|
61
|
+
"properties": {
|
|
62
|
+
"ok": {
|
|
63
|
+
"const": false
|
|
64
|
+
},
|
|
65
|
+
"namespace": {
|
|
66
|
+
"const": "ledger-repair"
|
|
67
|
+
},
|
|
68
|
+
"command": {
|
|
69
|
+
"enum": [
|
|
70
|
+
"number-repair-proposal",
|
|
71
|
+
"number-repair"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"contract_version": {
|
|
75
|
+
"const": 1
|
|
76
|
+
},
|
|
77
|
+
"state": {
|
|
78
|
+
"enum": [
|
|
79
|
+
"unchanged",
|
|
80
|
+
"unknown"
|
|
81
|
+
],
|
|
82
|
+
"description": "`unchanged` states that no ledger byte was written. `unknown` is reserved for an outcome this core could not resolve; it never accompanies a refusal raised before any write was attempted."
|
|
83
|
+
},
|
|
84
|
+
"error": {
|
|
85
|
+
"$ref": "https://github.com/lstutzman/wowbagger/schemas/common.json#/$defs/error"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|