wowbagger 0.1.0-alpha.9 → 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 +450 -0
- package/README.md +137 -65
- 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 +2 -2
- 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 +238 -57
- 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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,456 @@ consolidation. The first tagged release inherits this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.5.0-beta.0 - 2026-08-30
|
|
11
|
+
|
|
12
|
+
- Promote Wowbagger from alpha to beta while keeping `next` as the documented
|
|
13
|
+
prerelease channel and `latest` mirrored to the same newest prerelease.
|
|
14
|
+
|
|
15
|
+
- Existing ledgers can safely authorize standard `tags` corrections through
|
|
16
|
+
`extensions-provision`: dry-run and publication now require a valid complete
|
|
17
|
+
ledger, validate every historical occurrence against explicit
|
|
18
|
+
`string-list` authority, preserve all item bytes, and publish one canonical
|
|
19
|
+
no-clobber declaration.
|
|
20
|
+
|
|
21
|
+
- `claim-verify` now accepts optional `--id <item>` for target-scoped
|
|
22
|
+
verification while retaining strict repository-wide behavior when omitted.
|
|
23
|
+
All findings remain visible with `blocks_verification_scope`; work-claim API
|
|
24
|
+
version is now 3 while the legacy envelope marker remains 1.
|
|
25
|
+
|
|
26
|
+
- Journal-capacity exhaustion now preserves the public
|
|
27
|
+
`journal-capacity-exceeded` discriminator across claim, verification,
|
|
28
|
+
adoption, publication, and legacy mutation paths. Pre-publication refusals
|
|
29
|
+
remain exit 6 `claim-store-unavailable`, `unchanged`, with prior journal and
|
|
30
|
+
item bytes intact; genuine persistence failures and post-intent unknown
|
|
31
|
+
outcomes retain their existing classifications.
|
|
32
|
+
|
|
33
|
+
- Lock diagnostics now preserve valid `parent-migrate` and `snooze` owners,
|
|
34
|
+
matching the five-operation mutation contract. Unknown or malformed owner
|
|
35
|
+
metadata remains `owner: null` with `owner_diagnostic: "invalid-shape"`;
|
|
36
|
+
mutual exclusion and refusal behavior are unchanged.
|
|
37
|
+
|
|
38
|
+
- Batch create is permanently rejected for the direct-Markdown architecture.
|
|
39
|
+
`limits.multi_item_atomicity` remains `false`; serial
|
|
40
|
+
`create --auto-commit` calls in request order remain the supported bulk path,
|
|
41
|
+
with one invocation and one commit per item.
|
|
42
|
+
|
|
43
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
44
|
+
answers **The durable claim store is unavailable.** with
|
|
45
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14 create.
|
|
46
|
+
There is no automatic migration or mixed-version grace period. There is no
|
|
47
|
+
batch mutation. The create-then-commit loop, implemented most briefly as serial
|
|
48
|
+
`create --auto-commit`, remains the supported bulk path. Ledger item #186 records the
|
|
49
|
+
permanent no-batch decision, and item #182 owns existing duplicate numbers.
|
|
50
|
+
The fence adds no new Git roster or history
|
|
51
|
+
traversal and costs two extra fsync'd journal appends within the 65,536-entry
|
|
52
|
+
limit.
|
|
53
|
+
|
|
54
|
+
## 0.1.0-alpha.17 - 2026-08-30
|
|
55
|
+
|
|
56
|
+
- **Breaking:** raise the supported Node.js floor from 20 to 24. Node 20 and
|
|
57
|
+
Node 22 no longer satisfy `engines.node`; Node 26 remains outside the
|
|
58
|
+
supported matrix because of the separate Vitest incompatibility reported by
|
|
59
|
+
Lee.
|
|
60
|
+
|
|
61
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
62
|
+
answers **The durable claim store is unavailable.** with
|
|
63
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14 create.
|
|
64
|
+
There is no automatic migration or mixed-version grace period. There is no
|
|
65
|
+
batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
66
|
+
batch design, and item #182 owns existing duplicate numbers. The fence adds no
|
|
67
|
+
new Git roster or history traversal and costs two extra fsync'd journal appends
|
|
68
|
+
within the 65,536-entry limit.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## 0.1.0-alpha.16 - 2026-08-30
|
|
72
|
+
|
|
73
|
+
- Added `version-drift --json` to detect stale installed skill pins, core
|
|
74
|
+
contract versions, and package provenance before ledger mutation.
|
|
75
|
+
|
|
76
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
77
|
+
answers **The durable claim store is unavailable.** with
|
|
78
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14
|
|
79
|
+
create. There is no automatic migration or mixed-version grace period. There is
|
|
80
|
+
no batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
81
|
+
batch design, and item #182 owns existing duplicate numbers. The fence adds no
|
|
82
|
+
new Git roster or history traversal and costs two extra fsync'd journal appends
|
|
83
|
+
within the 65,536-entry limit.
|
|
84
|
+
|
|
85
|
+
## 0.1.0-alpha.15 - 2026-08-30
|
|
86
|
+
|
|
87
|
+
- **Duplicate-number recovery now has a separate `ledger-repair` contract
|
|
88
|
+
version 1.** Use the read-only `number-repair-proposal` command to review a
|
|
89
|
+
complete mapping, then apply it with `number-repair`. The repair path requires
|
|
90
|
+
duplicate-number errors to be the complete validation failure, preserves ULID
|
|
91
|
+
identities and relation values, uses the shared namespace fence, records
|
|
92
|
+
durable intent/final entries, and supports bounded auto-commit recovery.
|
|
93
|
+
|
|
94
|
+
The alpha.14 hard cutover remains the baseline: `claim-store-unavailable`
|
|
95
|
+
answers **The durable claim store is unavailable.** with
|
|
96
|
+
`claim-store-unreadable`; upgrade every writer before the first alpha.14
|
|
97
|
+
create. There is no automatic migration or mixed-version grace period. There is
|
|
98
|
+
no batch mutation, the create-then-commit loop remains supported, item #186 owns
|
|
99
|
+
batch design, and item #182 owns existing duplicate numbers.
|
|
100
|
+
The fence adds no new Git roster or history traversal and costs two extra
|
|
101
|
+
fsync'd journal appends within the 65,536-entry limit.
|
|
102
|
+
|
|
103
|
+
## 0.1.0-alpha.14 - 2026-08-29
|
|
104
|
+
|
|
105
|
+
### Changed
|
|
106
|
+
|
|
107
|
+
- **Upgrading is a hard cutover: upgrade every writer in one Git coordination
|
|
108
|
+
domain before the first alpha.14 create.** The journal grammar widened —
|
|
109
|
+
`legacy-mutation-intent` and `legacy-mutation` accept `command: "create-v1"`,
|
|
110
|
+
a create intent accepts `expected_revision: null`, and a create abort requires
|
|
111
|
+
`command: "create-v1"` with `observed_revision: null` — and an alpha.13 binary
|
|
112
|
+
cannot read the new create entry. Run against a ledger whose shared journal
|
|
113
|
+
already carries one, alpha.13's `create` exits 6 with `error.code`
|
|
114
|
+
`claim-store-unavailable`, message `The durable claim store is unavailable.`,
|
|
115
|
+
and `error.details.reason` `claim-store-unreadable`, leaves state unchanged,
|
|
116
|
+
and writes no item. Failing closed is the compatibility guarantee: an old
|
|
117
|
+
writer cannot commit another duplicate. It is also the operational limit,
|
|
118
|
+
because alpha.13 is immutable and can only emit that generic unreadable-store
|
|
119
|
+
message. Read it as "this repository was written by a newer Wowbagger; upgrade
|
|
120
|
+
this worktree to continue." There is no automatic migration and no
|
|
121
|
+
mixed-version grace period; a partial upgrade leaves the remaining alpha.13
|
|
122
|
+
worktrees unable to make claim-protected mutations until they move. Item #185
|
|
123
|
+
owns general version-drift detection; nothing here can retrofit a message into
|
|
124
|
+
an already-published executable. The new reader executes every journal
|
|
125
|
+
alpha.13 emitted, which is the backward-compatibility direction that had to
|
|
126
|
+
hold.
|
|
127
|
+
|
|
128
|
+
- **A create must be committed before the next mutation, and there is still no
|
|
129
|
+
batch operation.** A created item has no earlier authorized revision, so Git
|
|
130
|
+
`HEAD` is the only surface that can carry its authorized bytes; an uncommitted
|
|
131
|
+
create raises the global `git-finalization-required` barrier for every later
|
|
132
|
+
mutation, including the next create. It cannot occupy the authorized
|
|
133
|
+
predecessor/successor window a `patch` or `transition` may occupy, and that
|
|
134
|
+
window was never permission to skip a commit. The supported bulk pattern is
|
|
135
|
+
the create-then-commit loop — filing ten items is ten cycles, and
|
|
136
|
+
`--auto-commit` on each create is its shortest form. Safe batch design is
|
|
137
|
+
item #186.
|
|
138
|
+
|
|
139
|
+
- **The measured cost of the fence is two extra fsync'd journal appends.** A
|
|
140
|
+
provisioned create already took the namespace lock, replayed the journal,
|
|
141
|
+
loaded the ledger, read Git `HEAD`, and reconciled, so the fence adds no new
|
|
142
|
+
Git roster or history traversal to a clean create; on a 1,500-item fixture the
|
|
143
|
+
captured `git` invocation sequence is identical before and after. The durable
|
|
144
|
+
cost is journal growth: each successful create adds one intent and one
|
|
145
|
+
committed terminal, so with no other activity the 65,536-entry limit permits
|
|
146
|
+
at most 21,845 three-entry create cycles, and the 8 MiB byte limit may bind
|
|
147
|
+
first. Other claim and mutation activity lowers that ceiling. Capacity is
|
|
148
|
+
reserved before the intent append, so an exhausted journal refuses unchanged
|
|
149
|
+
rather than stranding an attempt. Journal compaction is not part of this
|
|
150
|
+
change.
|
|
151
|
+
|
|
152
|
+
### Fixed
|
|
153
|
+
|
|
154
|
+
- **Two worktrees can no longer commit two items carrying the same number.**
|
|
155
|
+
Through alpha.13, `create` was journal-silent by design: it derived
|
|
156
|
+
`1 + max(existing numbers)` from the items its own checkout held and recorded
|
|
157
|
+
nothing in the shared claim journal. Two worktrees that had not integrated
|
|
158
|
+
each other's commits therefore derived the same number and both published,
|
|
159
|
+
and they did not have to race to do it — a create today and a create tomorrow
|
|
160
|
+
collided just as reliably, because the loser was a stale checkout rather than
|
|
161
|
+
a lost race. `number` is immutable and `patch` correctly refuses it, so the
|
|
162
|
+
collision surfaced only at integration, as a global `duplicate-number`
|
|
163
|
+
validation failure that stopped the whole ledger. On a provisioned ledger,
|
|
164
|
+
`create` is now a journaled legacy mutation: under the shared namespace lock
|
|
165
|
+
it reconciles, validates the complete candidate ledger, reserves journal
|
|
166
|
+
capacity, appends a `legacy-mutation-intent` with `command: "create-v1"` and
|
|
167
|
+
`expected_revision: null` before any byte reaches the item path, publishes
|
|
168
|
+
atomically and no-clobber, verifies the exact bytes, and appends its terminal
|
|
169
|
+
— `legacy-mutation` when the bytes landed, or an abort carrying
|
|
170
|
+
`command: "create-v1"` and `observed_revision: null` when the path stayed
|
|
171
|
+
absent. Allocation is fenced in front of all of that: every global finding
|
|
172
|
+
blocks `create` as it blocks any write, and in addition any coordinated item
|
|
173
|
+
this checkout does not hold blocks `create`, because its number cannot be
|
|
174
|
+
read here. A stale revision of an item this checkout does hold stays
|
|
175
|
+
nonblocking, because a number is immutable. A fenced create refuses with
|
|
176
|
+
exit 6, `state: "unchanged"`, `error.code: "claim-store-unavailable"`,
|
|
177
|
+
`error.details.reason: "publication-reconciliation-required"`, and no item
|
|
178
|
+
file; integrate the named item, run `claim-verify` to exit 0, and resend the
|
|
179
|
+
same request ID to take the next number. **What this fixes and what it does
|
|
180
|
+
not:** it closes the reported PropertyCompass2 collision, so cooperating
|
|
181
|
+
alpha.14 worktrees of one clone that share one Git common directory can no
|
|
182
|
+
longer commit the same number, because every such create is visible through
|
|
183
|
+
the shared journal before publication even without branch integration.
|
|
184
|
+
Separate clones, separate machines, alpha.13 writers before the hard cutover,
|
|
185
|
+
and noncooperating writes stay outside that fence and still rely on branch
|
|
186
|
+
integration plus `validate`. A ledger that already carries duplicate numbers
|
|
187
|
+
is not repaired here; item #182 owns that fenced recovery. Core
|
|
188
|
+
`contract_version` stays `5` and the create success and refusal envelopes add,
|
|
189
|
+
remove, and rename no member.
|
|
190
|
+
|
|
191
|
+
- **`create --auto-commit` commits its reconciliation log with the item.**
|
|
192
|
+
Because create now owns journal entries, its commit set is exactly the created
|
|
193
|
+
item and `<ledger>/.wowbagger/reconcile-<namespace>.md`, and
|
|
194
|
+
`mutation-finalize` accepts that same two-path recovery token. Between the
|
|
195
|
+
fence landing and this fix, `create --auto-commit` failed outright with
|
|
196
|
+
`git-commit-failed`, `failure_stage: "prepare-commit-set"`, and
|
|
197
|
+
`reason: "tree-changed"`, because the commit set excluded a log the mutation
|
|
198
|
+
had just written. Owning that log is not absorbing what was already in it:
|
|
199
|
+
`create` still refuses a reconciliation log that was dirty before the
|
|
200
|
+
invocation, and every other dirty ledger path still refuses.
|
|
201
|
+
|
|
202
|
+
- **A revision Git can already reach is no longer an instruction to wait for
|
|
203
|
+
it.** When the expected revision was reachable only from a tag, a
|
|
204
|
+
remote-tracking ref, a branch no worktree had checked out, or a live worktree
|
|
205
|
+
on a detached `HEAD`, the `worktree-synchronization-required` finding rendered
|
|
206
|
+
the not-yet-reachable sentence: "wait for the owning worktree to commit, then
|
|
207
|
+
synchronize this worktree and run claim-verify." The commit already existed
|
|
208
|
+
and no named worktree was ever going to publish it, so that wait could not
|
|
209
|
+
end. Those cases now render: "Revision <revision> of <path> is reachable in
|
|
210
|
+
Git, but no active named worktree owner is established; inspect the reachable
|
|
211
|
+
history, restore or explicitly adopt reviewed bytes, then run claim-verify."
|
|
212
|
+
A revision no reachable commit carries keeps the not-yet-reachable sentence
|
|
213
|
+
and its wait, and an item that has never existed in this checkout keeps the
|
|
214
|
+
cannot-be-established sentence. **A consumer that matches on `remediation`
|
|
215
|
+
text must update its patterns:** a finding that used to match "not yet
|
|
216
|
+
reachable" now matches "reachable in Git" for the four reachable-unowned
|
|
217
|
+
cases. Nothing else moves. The `reason` stays
|
|
218
|
+
`worktree-synchronization-required`, the code stays `stale-write-detected`,
|
|
219
|
+
`owner_unavailable: true` with no `owner_ref` or `owner_commit` is unchanged,
|
|
220
|
+
the finding stays advisory — it blocks a mutation targeting its own item and
|
|
221
|
+
lets an unrelated mutation proceed — and core `contract_version` stays `5`,
|
|
222
|
+
because no field, code, reason, or scope changes and the text correction
|
|
223
|
+
replaces a false instruction.
|
|
224
|
+
|
|
225
|
+
### Documentation
|
|
226
|
+
|
|
227
|
+
- **Worktree identity and its refusals are now documented.** Alpha.13 shipped an
|
|
228
|
+
explicit worktree identity — an opaque random UUID a worktree creates once in
|
|
229
|
+
its private Git directory — and started recording it as the optional
|
|
230
|
+
`writer_worktree_id` member on `legacy-mutation-intent`, `legacy-mutation`,
|
|
231
|
+
`publish-intent`, and `publish-final` journal entries. Reconciliation reads it
|
|
232
|
+
to tell this worktree's own unreachable successor from a sibling's, which is
|
|
233
|
+
what turns that topology into a global `unauthorized-revision` barrier instead
|
|
234
|
+
of advisory `worktree-synchronization-required`. Alpha.13 also began refusing
|
|
235
|
+
before it classifies anything when two live worktrees answer to one UUID, or
|
|
236
|
+
when the worktree roster cannot be read to completion: exit 6
|
|
237
|
+
`claim-store-unavailable`, reason `claim-store-unreadable`, plus one new
|
|
238
|
+
`error.details.identity_diagnostic` carrying `duplicate-worktree-identity`
|
|
239
|
+
with `worktree_id` and `live_worktree_count`, or `worktree-enumeration-failed`
|
|
240
|
+
with no further member, and the same diagnostic inside
|
|
241
|
+
`auto-commit-preflight-failed` with `retryable: false`. All of that shipped
|
|
242
|
+
without a release note; the alpha.13 entry mentioned writer identity only in
|
|
243
|
+
passing while describing which callers read it. The work-claim contract
|
|
244
|
+
section 3.1, the mutation contract auto-commit preflight details, and the
|
|
245
|
+
installed skill now state the journal field, its alpha.12-and-earlier
|
|
246
|
+
compatibility (such entries stay valid, attribute nothing, and leave the
|
|
247
|
+
writer unknown), what the identity discloses in committed history, and both
|
|
248
|
+
diagnostics. Core `contract_version` stays `5` and no public request or
|
|
249
|
+
success envelope changes.
|
|
250
|
+
|
|
251
|
+
- **Owner evidence names only an active named worktree, and the contract now
|
|
252
|
+
says so.** Through alpha.12 the owner search was a reachability search, so a
|
|
253
|
+
finding could report `owner_ref` naming a tag, a remote-tracking ref, or a
|
|
254
|
+
branch no worktree had checked out — an owner that could never publish
|
|
255
|
+
anything, and an instruction to wait forever. Alpha.13 replaced that with the
|
|
256
|
+
live worktree roster: this checkout first, then live worktrees on a branch
|
|
257
|
+
ordered by branch ref and then path, with bare and prunable records excluded.
|
|
258
|
+
`owner_ref` is therefore always the branch of a live worktree. A revision
|
|
259
|
+
reachable only from a tag, a remote-tracking ref, an unchecked-out branch, or
|
|
260
|
+
a live worktree on a detached `HEAD` now reports `owner_unavailable: true` and
|
|
261
|
+
no `owner_ref`. That narrowing shipped in alpha.13 with no release note, and
|
|
262
|
+
the alpha.11 note promising that a finding "retains that `owner_ref` and
|
|
263
|
+
`owner_commit`" no longer describes those cases. The contract and the
|
|
264
|
+
installed skill now state the roster rule, the three distinct meanings of
|
|
265
|
+
`owner_unavailable`, and which remediation sentence each one gets.
|
|
266
|
+
|
|
267
|
+
- **Repository-wide `claim-verify` and target-scoped mutation are stated as
|
|
268
|
+
different questions.** The mutation contract still said a recorded write in
|
|
269
|
+
one worktree "refuses every mutation in the others", which target scoping
|
|
270
|
+
stopped being true before alpha.11. It now states the item scope, and both
|
|
271
|
+
contracts and the installed skill now say plainly that a successful mutation
|
|
272
|
+
is not proof of a globally clean claim store: `claim-verify` names no target,
|
|
273
|
+
so it stays exit 6 while any item in the repository carries a blocking
|
|
274
|
+
finding, including an unrelated one. Item #184 is open in triage to decide the
|
|
275
|
+
supported verification surface; nothing about that behavior changed here, and
|
|
276
|
+
a gate that demands a globally clean `claim-verify` on a repository with live
|
|
277
|
+
sibling work is still unsatisfiable.
|
|
278
|
+
|
|
279
|
+
- **A refused reconciliation still persists the clock floor.** Reconciliation
|
|
280
|
+
has written its clock entry before it classifies anything since work claims
|
|
281
|
+
were implemented, so a command that then refuses with
|
|
282
|
+
`publication-reconciliation-required` has already advanced the durable
|
|
283
|
+
monotonic floor to `max(physical_utc, previous_floor)`. Section 4 documented
|
|
284
|
+
the floor only for authoritative lease decisions, so the pre-decision advance
|
|
285
|
+
and its one observable consequence were undocumented: because the floor never
|
|
286
|
+
rolls back, a lease or fence observed expired at that floor can never read
|
|
287
|
+
live again, and a holder on a ledger whose floor runs ahead of its own wall
|
|
288
|
+
clock may find its lease expired the moment it asks after clearing a barrier.
|
|
289
|
+
Behavior is unchanged; the contract now says it.
|
|
290
|
+
|
|
291
|
+
- **The reconciliation topology classifier moved without changing an answer.**
|
|
292
|
+
The topology decision that was spread across owner lookup, diagnosis, and
|
|
293
|
+
scope inference now lives in one pure module,
|
|
294
|
+
`src/reconciliation-classifier.js`, which takes normalized evidence and
|
|
295
|
+
returns a typed decision. That type is internal: scope travels beside a
|
|
296
|
+
finding and no response has ever carried it, so a consumer must keep reading
|
|
297
|
+
the refusal rather than the `reason` string. Every public seam — reason,
|
|
298
|
+
blocking behavior, owner fields, remediation sentence, exit, state, and
|
|
299
|
+
envelope domain — is byte-identical to alpha.13 on every matrix row, which is
|
|
300
|
+
the whole point of the change and the only claim made for it. No behavior
|
|
301
|
+
shipped with it.
|
|
302
|
+
|
|
303
|
+
## 0.1.0-alpha.13 - 2026-08-28
|
|
304
|
+
|
|
305
|
+
### Fixed
|
|
306
|
+
|
|
307
|
+
- **Every reconciling command reads the same writer evidence.** `claim-verify`
|
|
308
|
+
and ordinary mutations named the worktree they spoke for when they
|
|
309
|
+
classified reconciliation; `publish-claimed`, `claim-adopt`, and the
|
|
310
|
+
`claim acquire`, `claim renew`, and `claim release` lifecycle commands did
|
|
311
|
+
not. An unreachable successor written by the current worktree therefore read
|
|
312
|
+
as advisory sibling synchronization on those surfaces, whose target scoping
|
|
313
|
+
let `publish-claimed` commit a publication and `claim acquire` grant a claim
|
|
314
|
+
in exactly the state a `patch` refused. `publish-claimed`, `claim acquire`,
|
|
315
|
+
and `claim renew` now report `unauthorized-revision` and refuse, matching
|
|
316
|
+
`claim-verify`. `claim release` stays available: it relinquishes authority
|
|
317
|
+
rather than extending it, and refusing it would strand the lease in the
|
|
318
|
+
worktree least able to clear the barrier, because no other worktree can take
|
|
319
|
+
the item over while the claim is held. The release compare-and-swap is
|
|
320
|
+
unchanged, so a wrong owner, epoch, or expiry still refuses with
|
|
321
|
+
`claim-conflict`. A genuine sibling successor and an authorization written
|
|
322
|
+
before writer identity existed remain advisory synchronization on every
|
|
323
|
+
surface. `claim-adopt` semantics are unchanged: it reports no reconciliation
|
|
324
|
+
diagnosis and stays available as the remedy. It now judges its own identity
|
|
325
|
+
bytes before the worktree roster, so its own malformed identity reports as
|
|
326
|
+
such instead of as a failed sibling enumeration.
|
|
327
|
+
|
|
328
|
+
### Known limitations
|
|
329
|
+
|
|
330
|
+
- **Creates in more than one worktree can commit duplicate item numbers, even
|
|
331
|
+
when the creates are sequential, and no sanctioned repair exists** (items
|
|
332
|
+
#181 and #182). Create is journal-silent, so nothing coordinates the number
|
|
333
|
+
it derives. Any two worktrees whose checkouts have not been integrated derive
|
|
334
|
+
the next schema-v2 `number` from the base each can see, and both derive the
|
|
335
|
+
same one. The two creates need not overlap in time: a create in one worktree
|
|
336
|
+
today and a create in another worktree tomorrow collide just as surely, so
|
|
337
|
+
long as neither worktree has seen the other's commit. Each create succeeds,
|
|
338
|
+
each refuses nothing, and reconciliation reports nothing. The collision only
|
|
339
|
+
exists once the branches are integrated. `validate` then fails globally with
|
|
340
|
+
`duplicate-number` on every colliding item, and because an invalid ledger
|
|
341
|
+
blocks every mutation, the whole ledger stops accepting work. `number` is
|
|
342
|
+
immutable and `patch` correctly rejects it, so Wowbagger currently offers no
|
|
343
|
+
operation that repairs the collision.
|
|
344
|
+
|
|
345
|
+
Until both items ship, serialize `create` through a single worktree, and run
|
|
346
|
+
`validate` immediately after you integrate branches so a collision surfaces
|
|
347
|
+
at the merge rather than at the next mutation.
|
|
348
|
+
|
|
349
|
+
The PropertyCompass repair — editing `number` in the item source by hand,
|
|
350
|
+
committing it, then running `claim-adopt` — was an emergency intervention
|
|
351
|
+
taken under an outage. It is **not a supported workaround**. It bypasses the
|
|
352
|
+
number-collision and reference checks every mutation performs, and it can
|
|
353
|
+
leave dangling `depends_on`, `related`, and parent references that nothing
|
|
354
|
+
reports. Do not adopt it as routine practice.
|
|
355
|
+
|
|
356
|
+
## 0.1.0-alpha.12 - 2026-08-28
|
|
357
|
+
|
|
358
|
+
### Fixed
|
|
359
|
+
|
|
360
|
+
- **Out-of-protocol local states remain global reconciliation barriers.**
|
|
361
|
+
Alpha.11 could misclassify an unknown committed revision, an authorized
|
|
362
|
+
working-tree predecessor over an unknown `HEAD`, or a working-tree deletion
|
|
363
|
+
over an authorized `HEAD` as advisory sibling synchronization when another
|
|
364
|
+
worktree owned the expected revision. `claim-verify` still failed, but an
|
|
365
|
+
unrelated mutation could proceed through the documented global barrier.
|
|
366
|
+
Alpha.12 classifies local state before owner and target scope, while genuine
|
|
367
|
+
authorized sibling predecessors remain target-scoped synchronization.
|
|
368
|
+
- **Windows report path resolution preserves the read-failure error class.**
|
|
369
|
+
Windows can report `ENOENT` where POSIX reports `ENOTDIR` when an output path
|
|
370
|
+
descends through a regular file. Report generation now recognizes that
|
|
371
|
+
non-directory ancestor and returns `report-read-failed` with
|
|
372
|
+
`resolve-output-path` and `ENOTDIR` before publication, instead of surfacing
|
|
373
|
+
`report-write-failed` with `EEXIST`.
|
|
374
|
+
|
|
375
|
+
## 0.1.0-alpha.11 - 2026-08-27
|
|
376
|
+
|
|
377
|
+
### Fixed
|
|
378
|
+
|
|
379
|
+
- **Uncommitted sibling revisions keep target-scoped reconciliation safe.**
|
|
380
|
+
Previously authorized predecessor bytes now identify an in-protocol sibling
|
|
381
|
+
window without turning genuine hand edits or same-branch regressions into
|
|
382
|
+
nonblocking findings.
|
|
383
|
+
Restoring earlier authorized bytes in the same working tree remains
|
|
384
|
+
`unauthorized-revision` when the current branch owns the expected revision.
|
|
385
|
+
Detached `HEAD` uses its reachable history for the same current-owner guard,
|
|
386
|
+
so it cannot turn that regression into advisory sibling synchronization.
|
|
387
|
+
When Git proves that a sibling ref owns the expected revision, the finding
|
|
388
|
+
retains that `owner_ref` and `owner_commit` instead of reporting the owner as
|
|
389
|
+
unavailable.
|
|
390
|
+
- **Journal-owning auto-commit rebuilds its derived reconciliation log.** Claim
|
|
391
|
+
decisions may dirty that tracked projection; patch, transition,
|
|
392
|
+
parent-migrate, snooze, and publish-claimed now validate and commit the rebuilt
|
|
393
|
+
log while every foreign dirty ledger path and create still refuse.
|
|
394
|
+
- **Claim-verification failures preserve their cause.** Preflight and
|
|
395
|
+
post-commit errors carry the underlying claim verification code and reason;
|
|
396
|
+
claim-store lock contention is retryable while persistent reconciliation is
|
|
397
|
+
not.
|
|
398
|
+
`mutation-finalize` recovery now carries the identical diagnostics without
|
|
399
|
+
inventing a `findings` member.
|
|
400
|
+
- **Auto-commit uses target scope before and after committing.** Unrelated
|
|
401
|
+
synchronization findings no longer turn a successfully committed mutation
|
|
402
|
+
into a reported post-commit failure; target-blocking findings remain fatal and
|
|
403
|
+
visible through claim-verify.
|
|
404
|
+
|
|
405
|
+
### Changed
|
|
406
|
+
|
|
407
|
+
- **Parent migration and snooze now have complete contract guidance.** The
|
|
408
|
+
contract and installed skill document their requests, CAS and date rules,
|
|
409
|
+
response domains, auto-commit behavior, and legacy journal fence-family
|
|
410
|
+
semantics. Parent-migrate help no longer invents a live-item restriction.
|
|
411
|
+
- **Parent and snooze fields are documented as dedicated mutations, not
|
|
412
|
+
create-once values.** Existing items can be repointed to or from an epic with
|
|
413
|
+
`parent-migrate`, and `snooze` can set or clear `snoozed_until`; `kind` and
|
|
414
|
+
`provenance` remain genuinely create-once.
|
|
415
|
+
- **Release numbering preserves the unpublished alpha.10 cut.** Alpha.10 was
|
|
416
|
+
cut and tagged but never published to npm. This release advances to alpha.11
|
|
417
|
+
instead of moving that tag, so tag identity remains immutable and the
|
|
418
|
+
registry history honestly skips alpha.10.
|
|
419
|
+
|
|
420
|
+
### Known limitations
|
|
421
|
+
|
|
422
|
+
- **Parent-migrate and snooze lock owners lose diagnostic detail.** Their real
|
|
423
|
+
lock still refuses every concurrent mutation, but the refusal currently
|
|
424
|
+
reports `owner: null` with `owner_diagnostic: "invalid-shape"`. Item #174
|
|
425
|
+
tracks restoring those owner details; mutual exclusion is unaffected.
|
|
426
|
+
- **Ownership classification still needs one consolidated topology audit.**
|
|
427
|
+
Items #173, #176, and #177 close every case identified so far. Item #178
|
|
428
|
+
remains open to audit the topology as one matrix because each point fix
|
|
429
|
+
revealed an adjacent gap.
|
|
430
|
+
|
|
431
|
+
## 0.1.0-alpha.10 - 2026-08-26
|
|
432
|
+
|
|
433
|
+
### Fixed
|
|
434
|
+
|
|
435
|
+
- **Cross-worktree reconciliation is target-scoped.** An unrelated item
|
|
436
|
+
mutation no longer refuses because another worktree has a committed revision.
|
|
437
|
+
When synchronization is required, the finding names the owning reference.
|
|
438
|
+
- **Fresh clones recover committed claim history.** Reconciliation hydrates an
|
|
439
|
+
empty local claim journal from the committed reconciliation log, while
|
|
440
|
+
lock-free claim reads project that history without writing. Invalid or
|
|
441
|
+
over-capacity committed sequences fail closed.
|
|
442
|
+
- **Auto-commit recovery handles refusal and no-op paths.** Refused preflight
|
|
443
|
+
checks no longer rewrite the tracked reconciliation log. The first
|
|
444
|
+
post-provision create works, byte-identical mutations commit only their log,
|
|
445
|
+
and `mutation-finalize` accepts the corresponding log-only recovery after
|
|
446
|
+
`HEAD` advances.
|
|
447
|
+
- **Parent migration and snooze expose their guarded write contracts.**
|
|
448
|
+
Both commands support auto-commit, report their own response domains, return
|
|
449
|
+
a single unchanged invalid-request envelope, and report stale parent
|
|
450
|
+
witnesses as conflicts.
|
|
451
|
+
- **Create reserves the `extensions` request container.** Item data must name
|
|
452
|
+
extension members directly so patch and extension declarations can address
|
|
453
|
+
them.
|
|
454
|
+
- **Auto-commit preflight reports retryability explicitly.** Only a held
|
|
455
|
+
auto-commit mutex is retryable.
|
|
456
|
+
- **CLI and release metadata stay discoverable and complete.** Help describes
|
|
457
|
+
claim verification and list requests, and the release-site manifest covers
|
|
458
|
+
historical version records.
|
|
459
|
+
|
|
10
460
|
## 0.1.0-alpha.9 - 2026-08-23
|
|
11
461
|
|
|
12
462
|
### Added
|