wowbagger 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/LICENSE +201 -0
- package/README.md +464 -0
- package/adapters/claude-code/entrypoint.js +19 -0
- package/adapters/claude-code/wowbagger-adapter.json +25 -0
- package/adapters/codex/entrypoint.js +11 -0
- package/adapters/codex/wowbagger-adapter.json +25 -0
- package/adapters/opencode/entrypoint.js +11 -0
- package/adapters/opencode/wowbagger-adapter.json +25 -0
- package/bin/wowbagger.js +7 -0
- package/package.json +51 -0
- package/skills/wowbagger/SKILL.md +136 -0
- package/src/adapter/approval.js +135 -0
- package/src/adapter/bootstrap.js +43 -0
- package/src/adapter/context.js +34 -0
- package/src/adapter/core-probe.js +231 -0
- package/src/adapter/describe.js +383 -0
- package/src/adapter/entrypoint-main.js +335 -0
- package/src/adapter/entrypoint-path.js +103 -0
- package/src/adapter/handoff.js +124 -0
- package/src/adapter/instructions.js +106 -0
- package/src/adapter/invoke.js +294 -0
- package/src/adapter/limits.js +26 -0
- package/src/adapter/manifest.js +93 -0
- package/src/adapter/messages.js +15 -0
- package/src/adapter/paths.js +88 -0
- package/src/adapter/process-outcome.js +1116 -0
- package/src/adapter/schema-helpers.js +60 -0
- package/src/claim-capabilities.js +54 -0
- package/src/claim-coordinator.js +85 -0
- package/src/claim-journal.js +236 -0
- package/src/claim-operations.js +138 -0
- package/src/claim-publication.js +739 -0
- package/src/claim-request.js +140 -0
- package/src/claim-store.js +198 -0
- package/src/cli.js +1130 -0
- package/src/dependencies.js +3 -0
- package/src/git-reconciliation.js +62 -0
- package/src/ledger.js +296 -0
- package/src/mint.js +32 -0
- package/src/mutation.js +1979 -0
- package/src/namespace.js +35 -0
- package/src/ready.js +85 -0
- package/src/request.js +246 -0
- package/src/schema-migration.js +300 -0
- package/src/validate.js +1208 -0
package/README.md
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
# wowbagger
|
|
2
|
+
|
|
3
|
+
**The backlog may be infinite. The next issue should not be ambiguous.**
|
|
4
|
+
|
|
5
|
+
Wowbagger is harness-neutral backlog coordination for coding agents, built on
|
|
6
|
+
plain Markdown and Git. It is intended to give agents durable work memory,
|
|
7
|
+
dependency-aware task selection, and auditable multi-worktree coordination without
|
|
8
|
+
putting a database or hosted service inside your repository.
|
|
9
|
+
|
|
10
|
+
> **Status: pre-alpha and self-hosted.** The standalone core validates a
|
|
11
|
+
> Markdown ledger, selects deterministic priority-ordered ready tasks, and
|
|
12
|
+
> implements guarded local `capabilities`, `inspect`, `create`, `transition`,
|
|
13
|
+
> and `patch` commands, plus `mint-id` for canonical item IDs. Its mutation
|
|
14
|
+
> scope is deliberately narrow: cooperative writers in one working copy, one
|
|
15
|
+
> item at a time. A Claude Code adapter and plugin ship from this
|
|
16
|
+
> repository; the adapter answers the negotiation surface of the harness-neutral
|
|
17
|
+
> contract and passes all 183 assertions across all 15 cases on native Darwin,
|
|
18
|
+
> although no manifest platform is claimed `supported` yet. The shipped core
|
|
19
|
+
> mutation contract and adapter contract are version 2; their frozen version 1
|
|
20
|
+
> definitions are not silently negotiated.
|
|
21
|
+
>
|
|
22
|
+
> On Git-backed ledgers, work claims coordinate cooperating agents through a
|
|
23
|
+
> durable journal in Git's shared common directory. `claim acquire` uses
|
|
24
|
+
> observed-state compare-and-swap. `publish-claimed` fences one item against
|
|
25
|
+
> the active owner generation and expected revision. `claim-verify` reconciles
|
|
26
|
+
> response-loss and post-merge outcomes. This is **merge-coordinated**, not
|
|
27
|
+
> `safe_exclusive_dispatch`: direct writes, hostile processes, other clones,
|
|
28
|
+
> and non-claim-aware tools can still bypass the protocol.
|
|
29
|
+
|
|
30
|
+
## Start here
|
|
31
|
+
|
|
32
|
+
Install the core CLI, then verify it:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npm install -g wowbagger@next # public npm prerelease
|
|
36
|
+
# or, from this release's Git tag:
|
|
37
|
+
# npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.1
|
|
38
|
+
wowbagger capabilities --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
In Claude Code, add the plugin:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/plugin marketplace add lstutzman/wowbagger
|
|
45
|
+
/plugin install wowbagger@wowbagger
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The plugin drives the installed core rather than bundling one, so a version
|
|
49
|
+
mismatch is detectable instead of silent: it reads `contract_version` from
|
|
50
|
+
`capabilities` and refuses when the core is absent or reports anything it does
|
|
51
|
+
not support. It will not fall back to editing ledger files by hand, because that
|
|
52
|
+
would bypass validation and atomic publication.
|
|
53
|
+
|
|
54
|
+
To use the core directly from a clone instead, see
|
|
55
|
+
[Core commands](#core-commands).
|
|
56
|
+
|
|
57
|
+
## Installation, compatibility, and security
|
|
58
|
+
|
|
59
|
+
### Installation routes
|
|
60
|
+
|
|
61
|
+
Wowbagger ships as an npm package with a single `wowbagger` binary. There are
|
|
62
|
+
two supported install routes:
|
|
63
|
+
|
|
64
|
+
- **npm registry** — `npm install -g wowbagger@next` installs the current
|
|
65
|
+
prerelease.
|
|
66
|
+
- **git tag** —
|
|
67
|
+
`npm install -g github:lstutzman/wowbagger#v0.1.0-alpha.1` installs this
|
|
68
|
+
release. Installing at a ref installs the core and every adapter that ref
|
|
69
|
+
carries.
|
|
70
|
+
|
|
71
|
+
Either route installs the core and the `wowbagger` command. The Claude Code
|
|
72
|
+
plugin is a separate artifact (see [Start here](#start-here)); the core and the
|
|
73
|
+
plugin are installed and versioned independently, and a mismatch is refused by
|
|
74
|
+
`contract_version` rather than guessed.
|
|
75
|
+
|
|
76
|
+
### Compatibility
|
|
77
|
+
|
|
78
|
+
The behavioural version is `contract_version`, reported by
|
|
79
|
+
`wowbagger capabilities --json`. Contracts change it; refactors do not. The
|
|
80
|
+
distribution version is the npm/git version, which names bytes, not behaviour.
|
|
81
|
+
Match on `contract_version` — never on the package version — when you decide
|
|
82
|
+
whether a core supports your request.
|
|
83
|
+
|
|
84
|
+
- **Node.js:** 20 and later. The adapter conformance vectors run against Node
|
|
85
|
+
20 and the current runtime before each release.
|
|
86
|
+
- **Platforms:** the core runs wherever Node.js runs, but a formal `supported`
|
|
87
|
+
platform claim is still `unverified` (they become verified per-platform only
|
|
88
|
+
with release evidence). Do not assume a platform is officially supported just
|
|
89
|
+
because the CLI starts.
|
|
90
|
+
- **Other tooling:** `wowbagger` manages a Git-tracked Markdown ledger. It
|
|
91
|
+
needs `git` present for work-claim and namespace operations.
|
|
92
|
+
|
|
93
|
+
### Security
|
|
94
|
+
|
|
95
|
+
- **Read-only by default.** `validate`, `ready`, `inspect`, `capabilities`, and
|
|
96
|
+
`mint-id` never modify anything. Every mutation (`create`, `transition`,
|
|
97
|
+
`patch`, and `publish-claimed`) is an explicit, reviewable write.
|
|
98
|
+
- **Lock is not a claim.** A short mutation lock serializes writers during one
|
|
99
|
+
operation. It does not grant a work claim.
|
|
100
|
+
- **Claims are merge-coordinated, not exclusive.** `claim acquire` uses
|
|
101
|
+
compare-and-swap against the observed claim state. `publish-claimed` checks
|
|
102
|
+
the active owner generation and expected ledger revision before it writes
|
|
103
|
+
one item. `claim-verify` records the final Git outcome and detects later
|
|
104
|
+
revision drift. Legacy `create` and `transition` refuse claim conflicts.
|
|
105
|
+
- **Local authority only.** The protocol protects cooperating worktrees in one
|
|
106
|
+
Git repository. It does not stop direct filesystem writes, hostile
|
|
107
|
+
processes, other clones, or alternate write paths. Capability discovery
|
|
108
|
+
therefore reports `mode: "merge-coordinated"` and
|
|
109
|
+
`safe_exclusive_dispatch: false`.
|
|
110
|
+
- **Supply chain.** Install only from the npm registry or this repository's
|
|
111
|
+
git tags, and verify the `contract_version` your adapter or script requires.
|
|
112
|
+
|
|
113
|
+
This README is documentation, not a substitute for the contracts. The
|
|
114
|
+
machinery behind these properties is specified in [SPEC.md](SPEC.md),
|
|
115
|
+
[docs/mutation-contract.md](docs/mutation-contract.md), and
|
|
116
|
+
[docs/work-claim-contract.md](docs/work-claim-contract.md).
|
|
117
|
+
|
|
118
|
+
## Upgrading from an earlier wowbagger
|
|
119
|
+
|
|
120
|
+
This section is written for agents as much as humans: if you already drive a
|
|
121
|
+
wowbagger core, this is how you move forward safely.
|
|
122
|
+
|
|
123
|
+
Upgrade the pieces you installed:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
npm install -g wowbagger@latest # public npm registry
|
|
127
|
+
npm install -g github:lstutzman/wowbagger # or: a direct git-tag install
|
|
128
|
+
git pull && npm ci # or: a direct checkout
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
In Claude Code, update the plugin the same way it was installed:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
/plugin marketplace update wowbagger
|
|
135
|
+
/plugin update wowbagger@wowbagger
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Then verify, exactly as on first install:
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
wowbagger capabilities --json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`contract_version` is the compatibility gate. The plugin and adapter refuse a
|
|
145
|
+
core that reports a version they do not support; if you automate against the
|
|
146
|
+
core directly, do the same rather than guessing.
|
|
147
|
+
|
|
148
|
+
The shipped adapter selects only adapter contract version 2 and requires core
|
|
149
|
+
contract version 2. A v1-only consumer receives
|
|
150
|
+
`unsupported-adapter-contract-version`; it does not receive v2 behavior. The
|
|
151
|
+
schema-2 transport is available. Ledger migration remains a separate quiesced
|
|
152
|
+
maintenance operation. The
|
|
153
|
+
[schema-2 migration runbook](docs/schema-2-migration.md) documents the required
|
|
154
|
+
backup, dry run, explicit `--apply`, lock refusal, and recovery procedure. The
|
|
155
|
+
tool is dry-run-only by default:
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
TMPDIR=/tmp node scripts/migrate-schema-2.js --ledger path/to/ledger
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Behaviour changes are recorded in [CHANGELOG.md](CHANGELOG.md) — read its
|
|
162
|
+
Unreleased section on every upgrade. If you automated against an earlier
|
|
163
|
+
core, these are the changes most likely to touch you:
|
|
164
|
+
|
|
165
|
+
- **Stop hand-editing frontmatter for priority or number.** `wowbagger patch`
|
|
166
|
+
changes both under the same revision compare-and-swap and per-ID lock as
|
|
167
|
+
`transition`. Hand-edits bypass validation and atomic publication.
|
|
168
|
+
- **Delete your local ULID generator.** `wowbagger mint-id --json` prints a
|
|
169
|
+
canonical ID; `--date YYYY-MM-DD` selects the creation date the ID must
|
|
170
|
+
encode.
|
|
171
|
+
- **Read `core.number` and `core.priority` from results** instead of decoding
|
|
172
|
+
`source_base64`. Every frontmatter field lives under `item.core`; `item.id`
|
|
173
|
+
is the one deliberate duplicate.
|
|
174
|
+
- **`ready` without `--json` is for you to read**: `#number pri=priority
|
|
175
|
+
title` per line, in ready order. Machine consumers keep `ready --json`,
|
|
176
|
+
which is byte-stable.
|
|
177
|
+
- **A claim request with an own `__proto__` member is now refused** as
|
|
178
|
+
`invalid-request` instead of silently losing the member.
|
|
179
|
+
- **`create` tells you where the item landed**: results report
|
|
180
|
+
`core.status: "triage"`, and the refusal for a caller-supplied `status`
|
|
181
|
+
names the accepting transition (triage to backlog) that makes an item
|
|
182
|
+
ready.
|
|
183
|
+
|
|
184
|
+
## Why the name?
|
|
185
|
+
|
|
186
|
+
Wowbagger the Infinitely Prolonged is a Douglas Adams character faced with an
|
|
187
|
+
absurdly large, strictly ordered list and the prospect of working through it
|
|
188
|
+
one entry at a time.
|
|
189
|
+
|
|
190
|
+
That is also a fair description of software maintenance.
|
|
191
|
+
|
|
192
|
+
The project is an independent literary nod and is not affiliated with or
|
|
193
|
+
endorsed by Douglas Adams' estate.
|
|
194
|
+
|
|
195
|
+
## The problem
|
|
196
|
+
|
|
197
|
+
Coding agents lose context. They are restarted, compacted, moved between
|
|
198
|
+
worktrees, or replaced by a different model. A useful backlog therefore cannot
|
|
199
|
+
live only in one conversation or one harness's private state.
|
|
200
|
+
|
|
201
|
+
Wowbagger makes the repository the durable coordination boundary:
|
|
202
|
+
|
|
203
|
+
- One inspectable Markdown file per backlog item.
|
|
204
|
+
- YAML metadata for lifecycle, priority, dependencies, and structured provenance.
|
|
205
|
+
- Git history as the audit log and recovery mechanism.
|
|
206
|
+
- Dependency-aware ready queues so an agent can ask what is actionable now.
|
|
207
|
+
- Guarded one-item creation and lifecycle transitions with exact-byte
|
|
208
|
+
revisions, cooperative locks, and explicit refusal when a change needs a
|
|
209
|
+
multi-item transaction.
|
|
210
|
+
- A documented adapter boundary for tool-capable agent harnesses, without
|
|
211
|
+
coupling the core to one vendor.
|
|
212
|
+
- Mechanical validation and derived reports instead of duplicated status data.
|
|
213
|
+
|
|
214
|
+
## Harness-neutral by design
|
|
215
|
+
|
|
216
|
+
Claude Code is an adapter, not the architecture. The core schema and command
|
|
217
|
+
interface will not depend on Claude-specific hooks, slash commands, paths, or
|
|
218
|
+
environment variables.
|
|
219
|
+
|
|
220
|
+
```mermaid
|
|
221
|
+
flowchart TD
|
|
222
|
+
Claude[Claude Code adapter] --> Core[Wowbagger core]
|
|
223
|
+
Codex[Codex adapter] --> Core
|
|
224
|
+
Other[Kimi and other tool-capable agents] --> Core
|
|
225
|
+
Core --> Markdown[Markdown and YAML backlog]
|
|
226
|
+
Core --> Git[Git audit and history]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The documented compatibility targets are:
|
|
230
|
+
|
|
231
|
+
- Claude Code
|
|
232
|
+
- OpenAI Codex
|
|
233
|
+
- Kimi and other OpenAI-compatible model APIs hosted in agent harnesses that
|
|
234
|
+
provide repository filesystem and command-execution tools
|
|
235
|
+
|
|
236
|
+
An OpenAI-compatible API describes model transport; it does not by itself
|
|
237
|
+
provide agent tools. The [adapter contract](docs/adapter-contract.md) records
|
|
238
|
+
the required host capabilities and refusal rules, and
|
|
239
|
+
[the integration guide](docs/openai-compatible-integration.md) states what a
|
|
240
|
+
Kimi or other OpenAI-compatible host can do today — driving the core CLI
|
|
241
|
+
directly — versus what a verifiable compatibility claim requires. Neither
|
|
242
|
+
claims that API compatibility alone makes a harness compatible.
|
|
243
|
+
|
|
244
|
+
This checkout ships three adapter packages on one shared entrypoint runtime:
|
|
245
|
+
[`adapters/claude-code/`](adapters/claude-code/), [`adapters/codex/`](adapters/codex/),
|
|
246
|
+
and [`adapters/opencode/`](adapters/opencode/). Each answers the section 3.3 bootstrap
|
|
247
|
+
wire with its own identity and honest host declaration. The native Darwin
|
|
248
|
+
Claude Code report passes all 183 assertions across all 15 cases — run
|
|
249
|
+
`node spec/run-adapter-implementation.js` to see the evidence. Codex and
|
|
250
|
+
OpenCode share the version 2 engine and execute all 183 assertions with
|
|
251
|
+
`--target codex` or `--target opencode`, but both target reports remain `fail`
|
|
252
|
+
pending target-specific evidence. Invocation forwarding, path and limit guards,
|
|
253
|
+
approval, and context all enter through the shared shipped engine. Platform
|
|
254
|
+
declarations remain `unverified` until their separate release evidence is
|
|
255
|
+
accepted. The Kimi and
|
|
256
|
+
OpenAI-compatible harness adapters are not written.
|
|
257
|
+
|
|
258
|
+
## Core commands
|
|
259
|
+
|
|
260
|
+
The current core requires Node.js 20 or later. From a Wowbagger checkout, `./bin/wowbagger.js --help`
|
|
261
|
+
prints the full command inventory, `./bin/wowbagger.js <command> --help` prints that
|
|
262
|
+
command's usage, and `./bin/wowbagger.js --version` prints the installed package
|
|
263
|
+
version. The commands below are the current inventory:
|
|
264
|
+
|
|
265
|
+
```sh
|
|
266
|
+
npm ci
|
|
267
|
+
./bin/wowbagger.js validate --ledger path/to/ledger --json
|
|
268
|
+
./bin/wowbagger.js ready --ledger path/to/ledger --as-of 2030-01-15 --json
|
|
269
|
+
./bin/wowbagger.js ready --ledger path/to/ledger --as-of 2030-01-15
|
|
270
|
+
./bin/wowbagger.js capabilities --json
|
|
271
|
+
./bin/wowbagger.js mint-id --json
|
|
272
|
+
./bin/wowbagger.js inspect --ledger path/to/ledger --id wb_... --json
|
|
273
|
+
./bin/wowbagger.js create --ledger path/to/ledger --input request.json --json
|
|
274
|
+
./bin/wowbagger.js transition --ledger path/to/ledger --input request.json --json
|
|
275
|
+
./bin/wowbagger.js patch --ledger path/to/ledger --input request.json --json
|
|
276
|
+
./bin/wowbagger.js provision --ledger path/to/ledger --json
|
|
277
|
+
./bin/wowbagger.js claim capabilities --ledger path/to/ledger --json
|
|
278
|
+
./bin/wowbagger.js claim acquire --ledger path/to/ledger --input request.json --json
|
|
279
|
+
./bin/wowbagger.js claim read --ledger path/to/ledger --input request.json --json
|
|
280
|
+
./bin/wowbagger.js claim renew --ledger path/to/ledger --input request.json --json
|
|
281
|
+
./bin/wowbagger.js claim release --ledger path/to/ledger --input request.json --json
|
|
282
|
+
./bin/wowbagger.js publish-claimed --ledger path/to/ledger --input request.json --json
|
|
283
|
+
./bin/wowbagger.js claim-verify --ledger path/to/ledger --json
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
`validate` writes exactly one JSON result to standard output. A valid ledger
|
|
287
|
+
returns:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{"valid":true,"errors":[]}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
`ready` validates first, then returns only the normative ready result:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{"as_of":"2030-01-15","valid":true,"ready":["wb_..."]}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
`validate` and `ready` require `--ledger`; `ready` also requires an ISO
|
|
300
|
+
calendar `--as-of` date. Without `--json`, `ready` prints a human queue —
|
|
301
|
+
`#number pri=priority title` per ready item — while `ready --json` stays
|
|
302
|
+
byte-stable for machine consumers. Invalid ledgers return the validation JSON and
|
|
303
|
+
exit nonzero. The core rejects invalid UTF-8, symbolic-link entries, unreadable
|
|
304
|
+
paths, and `.md` special files rather than returning a partial view. Real
|
|
305
|
+
directories ending in `.md` remain containers and are traversed. These checks
|
|
306
|
+
provide deterministic read hygiene; they are not a sandbox against a privileged
|
|
307
|
+
process racing filesystem changes.
|
|
308
|
+
|
|
309
|
+
`inspect` returns a lossless raw-byte snapshot and its SHA-256 revision.
|
|
310
|
+
`create` publishes only a caller-supplied canonical ID through atomic
|
|
311
|
+
no-clobber publication — `mint-id` prints one, so no consumer writes base32
|
|
312
|
+
by hand. `transition` compares the inspected revision while cooperative
|
|
313
|
+
per-ID locks are held, then changes one lifecycle item or refuses the request
|
|
314
|
+
if dependent cleanup or child disposition would require changing another
|
|
315
|
+
item. `patch` changes the caller-supplied `number` and `priority` fields —
|
|
316
|
+
nothing else — under the same lock and compare-and-swap. See
|
|
317
|
+
[the mutation contract](docs/mutation-contract.md) for the JSON request,
|
|
318
|
+
response, recovery, and scope details.
|
|
319
|
+
|
|
320
|
+
`provision` binds one ledger namespace to the repository. `claim` manages
|
|
321
|
+
durable acquire, read, renew, and release decisions. `publish-claimed` accepts
|
|
322
|
+
the exact candidate item bytes and fences their publication against the active
|
|
323
|
+
owner generation and expected revision. `claim-verify` reconciles pending
|
|
324
|
+
publication outcomes against the working tree and Git `HEAD`; run it after a
|
|
325
|
+
claimed publication is committed or merged, and before the next fenced
|
|
326
|
+
operation. See [the work-claim contract](docs/work-claim-contract.md) for the
|
|
327
|
+
request envelopes, refusal precedence, recovery rules, and the difference
|
|
328
|
+
between strict fenced and merge-coordinated backends.
|
|
329
|
+
|
|
330
|
+
The `contract_version` reported by `capabilities` is what an adapter or plugin
|
|
331
|
+
declares it requires. A consumer pairing one with a core that reports a
|
|
332
|
+
different contract version gets a refusal, not a guess. Direct checkout use —
|
|
333
|
+
`./bin/wowbagger.js` from a clone — remains supported and is what this
|
|
334
|
+
repository's own ledger uses.
|
|
335
|
+
|
|
336
|
+
## Verify a checkout
|
|
337
|
+
|
|
338
|
+
The development workflow is intentionally self-hosted: edit code and ledger
|
|
339
|
+
fixtures locally, run the deterministic checks, and review the resulting Git
|
|
340
|
+
diff. Node.js 20 or later is required.
|
|
341
|
+
|
|
342
|
+
```sh
|
|
343
|
+
npm ci
|
|
344
|
+
npm test
|
|
345
|
+
npm audit --omit=dev
|
|
346
|
+
git diff --check
|
|
347
|
+
./bin/wowbagger.js validate --ledger ledger --json
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
The work-claim contract has normative documentation and fixtures in
|
|
351
|
+
[`docs/work-claim-contract.md`](docs/work-claim-contract.md). The shipped
|
|
352
|
+
Git-backed profile is merge-coordinated and deliberately does not claim
|
|
353
|
+
`safe_exclusive_dispatch`.
|
|
354
|
+
|
|
355
|
+
## This repository's ledger
|
|
356
|
+
|
|
357
|
+
Wowbagger dogfoods its own draft format in the repository-local
|
|
358
|
+
[`ledger/`](ledger/) directory. Two epics divide the work, and the boundary is
|
|
359
|
+
clean: if it changes what the core does it belongs to standalone v0; if it
|
|
360
|
+
changes how the core reaches a consumer it belongs to productization. A
|
|
361
|
+
separate, triage-only item records a possible future PropertyCompass backlog
|
|
362
|
+
migration as a deferred consumer decision, gated on merge-coordinated work
|
|
363
|
+
claims and an explicit adoption decision. From a
|
|
364
|
+
checkout, query the ledger with the current UTC date in place of `YYYY-MM-DD`:
|
|
365
|
+
|
|
366
|
+
```sh
|
|
367
|
+
./bin/wowbagger.js validate --ledger ledger --json
|
|
368
|
+
./bin/wowbagger.js ready --ledger ledger --as-of YYYY-MM-DD --json
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the small set of ledger-maintenance
|
|
372
|
+
rules and the limits of the local mutation runtime.
|
|
373
|
+
|
|
374
|
+
## Design principles
|
|
375
|
+
|
|
376
|
+
1. **Markdown is canonical.** Humans can inspect and edit the backlog using
|
|
377
|
+
ordinary repository tools.
|
|
378
|
+
2. **Git provides auditability and conflict detection.** Do not introduce a
|
|
379
|
+
second version-control system or an opaque synchronization layer.
|
|
380
|
+
3. **Derived state stays derived.** Ready queues, epic progress, and reports are
|
|
381
|
+
computed rather than stored twice.
|
|
382
|
+
4. **Mechanism and policy are separate.** Lifecycle and generic ledger
|
|
383
|
+
mechanics can be reused while each host repository keeps its own priorities
|
|
384
|
+
and vocabulary.
|
|
385
|
+
5. **Adapters stay thin.** Harness packaging translates into the stable core;
|
|
386
|
+
it does not fork core behavior.
|
|
387
|
+
6. **The implementation remains auditable.** Coordination tooling should be
|
|
388
|
+
small enough for a human to understand and repair.
|
|
389
|
+
|
|
390
|
+
## Repository shape
|
|
391
|
+
|
|
392
|
+
```text
|
|
393
|
+
src/ The core, and the shared adapter engine in src/adapter/
|
|
394
|
+
bin/ The wowbagger executable
|
|
395
|
+
adapters/ Harness packaging — claude-code, codex, and opencode packages
|
|
396
|
+
skills/ Portable agent workflows shipped by the plugin
|
|
397
|
+
spec/ Ledger schema, the adapter reference model, and normative fixtures
|
|
398
|
+
test/ The test suite
|
|
399
|
+
docs/ Contracts, integration guidance, and handoffs
|
|
400
|
+
scripts/ Maintenance commands that stay outside the core mutation contract
|
|
401
|
+
ledger/ This repository's own backlog, managed by wowbagger itself
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
`spec/adapter-reference.js` is an independent oracle. `src/adapter/`
|
|
405
|
+
deliberately re-implements it rather than importing it, and a differential test
|
|
406
|
+
holds the two together — the same arrangement `src/claim-request.js` has with
|
|
407
|
+
`test/work-claim-reference.js`. Collapsing either pair into a shared
|
|
408
|
+
implementation would make its conformance tests prove nothing.
|
|
409
|
+
|
|
410
|
+
The layout may change before the first release. The separation between the core
|
|
411
|
+
and its adapters will not.
|
|
412
|
+
|
|
413
|
+
## What Wowbagger is not
|
|
414
|
+
|
|
415
|
+
- An autonomous software factory or agent scheduler.
|
|
416
|
+
- A hosted issue tracker.
|
|
417
|
+
- A hidden agent-memory database.
|
|
418
|
+
- A Claude Code-only plugin.
|
|
419
|
+
- A replacement for engineering judgment about what should be built.
|
|
420
|
+
|
|
421
|
+
It is the durable work ledger beneath those systems.
|
|
422
|
+
|
|
423
|
+
## Roadmap
|
|
424
|
+
|
|
425
|
+
- Publish a standalone Markdown ledger contract and synthetic compatibility
|
|
426
|
+
fixtures.
|
|
427
|
+
- Provide read-only validation and deterministic ready selection by creation
|
|
428
|
+
order before mutable coordination. **Implemented in this checkout; not yet a
|
|
429
|
+
stable release.**
|
|
430
|
+
- Implement the local-filesystem inspect, create, and single-item
|
|
431
|
+
lifecycle-transition contract, including lossless exact-byte inspection,
|
|
432
|
+
caller-known IDs, atomic no-clobber creation or refusal, and explicit
|
|
433
|
+
multi-item refusal. **Implemented and covered by black-box vectors; still
|
|
434
|
+
pre-alpha and intentionally local in scope.**
|
|
435
|
+
- Separate optional reusable mechanisms from consumer-specific policy.
|
|
436
|
+
- Stabilize the machine-readable command contract and compatibility evidence.
|
|
437
|
+
- Ship Claude Code and Codex adapters. **Claude Code, Codex, and OpenCode
|
|
438
|
+
packages share the version 2 engine; the Claude Code Darwin target passes
|
|
439
|
+
all 183 assertions, while the other target reports and all manifest platform
|
|
440
|
+
declarations remain unverified.**
|
|
441
|
+
- Document the generic tool contract for other agent harnesses.
|
|
442
|
+
- Implement merge-coordinated work claims for cooperating Git worktrees.
|
|
443
|
+
**Implemented with durable claim operations, claim-protected single-item
|
|
444
|
+
publication, and Git reconciliation. It deliberately reports
|
|
445
|
+
`safe_exclusive_dispatch: false`; direct writes and other uncoordinated paths
|
|
446
|
+
remain bypasses.**
|
|
447
|
+
- Treat any PropertyCompass adoption as a later, separately-scoped consumer
|
|
448
|
+
project.
|
|
449
|
+
|
|
450
|
+
## Contributing
|
|
451
|
+
|
|
452
|
+
The project has a pre-alpha standalone core. Issues describing concrete
|
|
453
|
+
portability requirements, coordination failures, or harness-integration
|
|
454
|
+
constraints are welcome. Please avoid proposing harness-specific behavior in
|
|
455
|
+
the core when it can live in an adapter.
|
|
456
|
+
|
|
457
|
+
For a change, create a focused branch, keep ledger edits reviewable, run the
|
|
458
|
+
verification commands above, and open a pull request with the tests and
|
|
459
|
+
contract links that justify the change. Do not claim support for an adapter or
|
|
460
|
+
fenced backend until its contract and implementation have merged.
|
|
461
|
+
|
|
462
|
+
## License
|
|
463
|
+
|
|
464
|
+
Licensed under the [Apache License 2.0](LICENSE).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runAdapterEntrypoint, standardDynamicResult } from '../../src/adapter/entrypoint-main.js';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
|
|
6
|
+
// The honest host declaration for the Claude Code harness. The shared
|
|
7
|
+
// launch discipline applies unchanged; override members here the moment
|
|
8
|
+
// this harness's real guarantees diverge.
|
|
9
|
+
await runAdapterEntrypoint({
|
|
10
|
+
manifestUrl: process.env.WOWBAGGER_ADAPTER_MANIFEST_PATH
|
|
11
|
+
? pathToFileURL(path.resolve(process.env.WOWBAGGER_ADAPTER_MANIFEST_PATH))
|
|
12
|
+
: new URL('./wowbagger-adapter.json', import.meta.url),
|
|
13
|
+
packageRoot: fileURLToPath(new URL('../..', import.meta.url)),
|
|
14
|
+
workspaceConfigUrl: process.env.WOWBAGGER_ADAPTER_WORKSPACES_PATH
|
|
15
|
+
? pathToFileURL(path.resolve(process.env.WOWBAGGER_ADAPTER_WORKSPACES_PATH))
|
|
16
|
+
: undefined,
|
|
17
|
+
dynamicResult: standardDynamicResult,
|
|
18
|
+
});
|
|
19
|
+
process.exit(0);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adapter_manifest_version": 1,
|
|
3
|
+
"adapter_id": "dev.wowbagger.adapter.claude-code",
|
|
4
|
+
"adapter_version": "0.1.0",
|
|
5
|
+
"adapter_contract_versions": [2],
|
|
6
|
+
"bootstrap_wire_version": 1,
|
|
7
|
+
"required_core_contract_version": 2,
|
|
8
|
+
"entrypoints": {
|
|
9
|
+
"describe": {
|
|
10
|
+
"kind": "command",
|
|
11
|
+
"executable": "adapters/claude-code/entrypoint.js",
|
|
12
|
+
"fixed_args": ["describe"]
|
|
13
|
+
},
|
|
14
|
+
"invoke": {
|
|
15
|
+
"kind": "command",
|
|
16
|
+
"executable": "adapters/claude-code/entrypoint.js",
|
|
17
|
+
"fixed_args": ["invoke"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"platforms": {
|
|
21
|
+
"darwin": "unverified",
|
|
22
|
+
"linux": "unverified",
|
|
23
|
+
"win32": "unverified"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runAdapterEntrypoint, standardDynamicResult } from '../../src/adapter/entrypoint-main.js';
|
|
3
|
+
|
|
4
|
+
// The honest host declaration for the Codex CLI harness (`codex exec`).
|
|
5
|
+
// The shared launch discipline applies unchanged; override members here
|
|
6
|
+
// the moment this harness's real guarantees diverge.
|
|
7
|
+
await runAdapterEntrypoint({
|
|
8
|
+
manifestUrl: new URL('./wowbagger-adapter.json', import.meta.url),
|
|
9
|
+
dynamicResult: standardDynamicResult,
|
|
10
|
+
});
|
|
11
|
+
process.exit(0);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adapter_manifest_version": 1,
|
|
3
|
+
"adapter_id": "dev.wowbagger.adapter.codex",
|
|
4
|
+
"adapter_version": "0.1.0",
|
|
5
|
+
"adapter_contract_versions": [2],
|
|
6
|
+
"bootstrap_wire_version": 1,
|
|
7
|
+
"required_core_contract_version": 2,
|
|
8
|
+
"entrypoints": {
|
|
9
|
+
"describe": {
|
|
10
|
+
"kind": "command",
|
|
11
|
+
"executable": "adapters/codex/entrypoint.js",
|
|
12
|
+
"fixed_args": ["describe"]
|
|
13
|
+
},
|
|
14
|
+
"invoke": {
|
|
15
|
+
"kind": "command",
|
|
16
|
+
"executable": "adapters/codex/entrypoint.js",
|
|
17
|
+
"fixed_args": ["invoke"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"platforms": {
|
|
21
|
+
"darwin": "unverified",
|
|
22
|
+
"linux": "unverified",
|
|
23
|
+
"win32": "unverified"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runAdapterEntrypoint, standardDynamicResult } from '../../src/adapter/entrypoint-main.js';
|
|
3
|
+
|
|
4
|
+
// The honest host declaration for the opencode harness. The shared launch
|
|
5
|
+
// discipline applies unchanged; override members here the moment this
|
|
6
|
+
// harness's real guarantees diverge.
|
|
7
|
+
await runAdapterEntrypoint({
|
|
8
|
+
manifestUrl: new URL('./wowbagger-adapter.json', import.meta.url),
|
|
9
|
+
dynamicResult: standardDynamicResult,
|
|
10
|
+
});
|
|
11
|
+
process.exit(0);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adapter_manifest_version": 1,
|
|
3
|
+
"adapter_id": "dev.wowbagger.adapter.opencode",
|
|
4
|
+
"adapter_version": "0.1.0",
|
|
5
|
+
"adapter_contract_versions": [2],
|
|
6
|
+
"bootstrap_wire_version": 1,
|
|
7
|
+
"required_core_contract_version": 2,
|
|
8
|
+
"entrypoints": {
|
|
9
|
+
"describe": {
|
|
10
|
+
"kind": "command",
|
|
11
|
+
"executable": "adapters/opencode/entrypoint.js",
|
|
12
|
+
"fixed_args": ["describe"]
|
|
13
|
+
},
|
|
14
|
+
"invoke": {
|
|
15
|
+
"kind": "command",
|
|
16
|
+
"executable": "adapters/opencode/entrypoint.js",
|
|
17
|
+
"fixed_args": ["invoke"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"platforms": {
|
|
21
|
+
"darwin": "unverified",
|
|
22
|
+
"linux": "unverified",
|
|
23
|
+
"win32": "unverified"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/bin/wowbagger.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wowbagger",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Plain-Markdown, Git-native work ledger for coordinating agents — validate, ready-select, and mutate a task ledger from the CLI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Lee Stutzman"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/lstutzman/wowbagger",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/lstutzman/wowbagger.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/lstutzman/wowbagger/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ledger",
|
|
20
|
+
"task-management",
|
|
21
|
+
"backlog",
|
|
22
|
+
"coordination",
|
|
23
|
+
"agent",
|
|
24
|
+
"markdown",
|
|
25
|
+
"git",
|
|
26
|
+
"cli"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
31
|
+
"bin": {
|
|
32
|
+
"wowbagger": "bin/wowbagger.js"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"bin",
|
|
36
|
+
"src",
|
|
37
|
+
"skills",
|
|
38
|
+
"adapters",
|
|
39
|
+
"README.md",
|
|
40
|
+
"CHANGELOG.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"check": "npm test && git diff --check && git diff --cached --check",
|
|
45
|
+
"test": "node --test test/*.test.js",
|
|
46
|
+
"prepublishOnly": "node bin/wowbagger.js validate --ledger ledger --json >/dev/null && node --check bin/wowbagger.js"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"yaml": "^2.9.0"
|
|
50
|
+
}
|
|
51
|
+
}
|