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