luciazero 2.2.0 → 2.4.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 DELETED
@@ -1,641 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project are documented in this file.
4
-
5
- Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
- Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- ## [2.2.0] - 2026-08-15
11
-
12
- ### Added
13
-
14
- - `/imouto-mode` adds Lucia's optional warm, lightly tsundere younger-sister
15
- coding voice. It is explicit-only, off by default, invocation-scoped, and
16
- keeps technical work, safety, and verification ahead of persona.
17
-
18
- ## [2.1.0] - 2026-08-15
19
-
20
- ### Added
21
-
22
- - `/show` turns code relationships, structural changes, and verification
23
- evidence into the smallest useful traceable visual.
24
- - `./test.sh --fast` provides a measured intermediate tier while the default
25
- and `--full` preserve complete CI/closeout coverage.
26
- - Opt-in Claude hooks use private per-session scratch state to record
27
- privacy-preserving aggregate turn/merged-Bash wall time and Bash, failed or
28
- successful verify, and model/user skill counts; `luciazero discipline`
29
- summarizes them.
30
-
31
- ### Changed
32
-
33
- - `/luciazero-bootstrap` is now `/ready`. The old command remains as a
34
- deprecated compatibility alias for one release.
35
- - The doctrine reserves full verification for closeout, and `/plan` plus
36
- `/debug` no longer auto-trigger for routine edits or first obvious failures.
37
-
38
- ## [2.0.3] - 2026-08-13
39
-
40
- ### Fixed
41
-
42
- - The Claude plugin now exposes its reviewer from the default root `agents/`
43
- directory. Claude Code 2.1.227 validated the former custom manifest path but
44
- reported and loaded zero agents; the default layout reports one. CI requires
45
- the plugin mirror to match the classic install source byte-for-byte and
46
- prevents the custom path from returning.
47
-
48
- ## [2.0.2] - 2026-08-13
49
-
50
- ### Fixed
51
-
52
- - `/lucia-relay` now records whether its recipient is on the same machine or a
53
- different one before producing pointers. Schema 2 permits full paths only
54
- for same-machine delivery; cross-machine validation requires a clean HEAD
55
- reachable from a locally known remote branch, rejects machine-only paths,
56
- and provides `knowledge.inline` for otherwise-local context. Schema 1 relays
57
- remain readable as same-machine-only legacy artifacts, and legacy `draft`
58
- callers without `--recipient` safely default to same-machine delivery.
59
-
60
- ## [2.0.1] - 2026-08-13
61
-
62
- ### Added
63
-
64
- - **Explicit, channel-aware updates.** `npx luciazero@latest check-update`
65
- performs a read-only, five-second npm registry check only when invoked;
66
- `npx luciazero@latest update` detects classic Claude, its hook mode, and
67
- Codex, then refreshes every detected install through the existing audited
68
- installers. It refuses to create a fresh install, downgrade a recognized
69
- newer one, or trust a malformed version sidecar. Legacy installs without the
70
- sidecar remain updatable. Classic doctrine customization now receives the
71
- same managed-snapshot backup protection as skills and agents.
72
- Plugin and skills-only update commands, Claude plugin auto-update, and GitHub
73
- release notifications are documented separately in both READMEs.
74
-
75
- ### Changed
76
-
77
- - The release workflow uses the runner's GitHub CLI instead of a Node 20-based
78
- release action. Re-runs replace the existing zip without recreating the
79
- release, and GitHub Actions no longer emits the deprecated-runtime warning.
80
-
81
- ## [2.0.0] - 2026-08-13
82
-
83
- ### Changed
84
-
85
- - The canonical Sonnet result is explicitly preliminary (`+31pp`, n=4–5).
86
- The historical `+37pp` statement is retired because its eight replacement
87
- raw rows could not be recovered.
88
- - `eval/report.sh` rejects mixed campaigns/commits/seeds, changed fixture
89
- hashes, duplicate invocation IDs, and inconsistent pair order. Published
90
- evidence also enforces registered task/arm/row/invalid/model expectations,
91
- and discloses Haiku's incomplete per-row model provenance.
92
- - Eval tasks may provide deterministic offline setup before either arm. Provider
93
- transcripts now live outside worked trees so they cannot alter Git status,
94
- repository fingerprints, or final-tree grading.
95
- - Relay fingerprints encode untracked special files without opening them, so a
96
- FIFO, socket, or device cannot block inspection or trigger device I/O.
97
- - GitHub workflows use the Node 24-based `actions/checkout@v5` and
98
- `actions/setup-node@v5` runtimes.
99
- - **Breaking: `/handoff` is now `/lucia-relay`.** The branded name avoids
100
- collisions with generic handoff skills. Installs remove an untouched v1.5
101
- copy but preserve and warn about customized copies. Relay state is now a
102
- validated `LUCIA_RELAY.json` manifest plus a generated human view, with a
103
- repository fingerprint, verification evidence, negative knowledge,
104
- cross-session/cross-agent routing, drift inspection, and explicit consume.
105
- - **Risk-routed review.** The single portable reviewer now accepts `general`,
106
- `security`, and `contract` focus modes, reads callers/consumers, and uses one
107
- blocker/major/minor policy. `/done` requests separate focused passes when a
108
- diff crosses both security and contract boundaries.
109
- - **Smart verification is repo-owned.** Monorepos create `verify-changed` from
110
- their native task graph and keep `verify-full` for closeout. The global hook
111
- never guesses dependency impact from path prefixes.
112
- - **Classic and Codex installs track component ownership.** Exact hidden
113
- snapshots distinguish Luciazero-managed skills/agents from same-name user or
114
- third-party components. Updates back up collisions/customizations, and
115
- uninstall removes only an unchanged managed copy.
116
-
117
- ### Added
118
-
119
- - Auditable benchmark evidence: canonical Claude raw JSONL, a SHA-256 campaign
120
- registry, generated README/benchmark tables, and a CI drift check.
121
- - Result schema 2 records campaign, pair, invocation, repository, fixture,
122
- prompt, platform, and arm-order metadata. Seeded arm randomization reduces
123
- fixed-order bias without making campaigns irreproducible.
124
- - Strict shared result validation rejects unsupported schemas and mistyped
125
- booleans, criteria, metrics, timestamps, platform, and campaign metadata.
126
- Output-aware `--resume` fills interrupted pairs without rerunning completed
127
- invocation IDs; `--run-offset` extends completed batches.
128
- - Three zero-quota candidate eval tasks cover archive extraction security,
129
- lossless atomic schema migration, and multi-page cursor integration. Each
130
- grader proves reference/project/anti-gamed behavior offline.
131
- - **`relay-transfer` protocol eval** grades portable state, an exact next edit,
132
- verification evidence, negative knowledge, scope preservation, and a current
133
- repository fingerprint. CI proves its 6/6 reference and rejects generic
134
- prose plus a content-complete stale relay without spending model quota.
135
- - **Lucia Relay demo** drives the shipped producer/receiver implementation in
136
- a temporary Git repository: render, validate, detect drift, re-run evidence,
137
- and explicitly consume. The checked-in GIF is generated from the same script
138
- exercised by CI.
139
- - **Central component catalogs** drive classic/Codex install, status,
140
- uninstall, and inventory tests, so a new skill or agent cannot silently ship
141
- through only one channel.
142
- - **`/plan`** defines falsifiable acceptance signals and reversible steps,
143
- while pausing for approval only on ambiguity, high stakes, destructive work,
144
- public-contract choices, or scope changes.
145
- - **`/bisect` + `safe-bisect.sh`** locate the first bad commit in a detached
146
- temporary worktree, repeat endpoints to catch flakes, preserve exit 125
147
- skips, distinguish missing commands, and clean every exit path.
148
- - **`npx luciazero discipline` + `/discipline-report`** analyze schema-v2
149
- local JSONL outcomes with day/project filters and JSON output. The hook logs
150
- a privacy-preserving project hash and verify mode; legacy records remain
151
- readable and recommendations distinguish observations from likely causes.
152
- - **`/lucia-relay` carries memory pointers** — the `Read first`
153
- section quotes the `docs/lessons.md` entries relevant to the unfinished
154
- work (a selection, never a copy — the ledger travels with the repo) and
155
- copies applicable machine-local `luciazero-heuristics.md` entries
156
- verbatim, since the relay is the only way those cross machines. The
157
- consume protocol tells the reader to follow the pointers before touching
158
- code and to adopt carried heuristics that earn their keep.
159
-
160
- - **`eval/run.sh --use-login`** — run the real eval on an existing Claude
161
- subscription (Pro/Max) instead of API dollars: seeds each per-run sandbox
162
- config dir with this machine's login state — `~/.claude.json`, plus
163
- OAuth tokens from `.credentials.json` (Linux) or a Keychain export
164
- (macOS). The copy lives only inside the mktemp sandbox and is deleted
165
- with it. Fail-soft by
166
- design: if the seed does not authenticate, `check-result.sh` marks the
167
- arm INVALID and nothing is spent. Plumbing (seed per arm, warn on missing
168
- login state) is proven offline in `test.sh`.
169
-
170
- - **`eval/check-result.sh`** — a zero exit code no longer proves the agent
171
- ran: the CLI has wrapped a `Not logged in` error in subtype `"success"`
172
- (observed 2026-08-11, caught free by a 1-run smoke). The guard inspects
173
- the result payload (`is_error`, `terminal_reason: api_error`, login
174
- errors) and `run.sh` books a refuted arm as INVALID with the reason
175
- quoted; every accept/reject path is fixture-proven in `test.sh`.
176
- - **`eval/run.sh --offline`** — synthetic smoke mode: no `claude` CLI, no
177
- API key, zero cost. Doctrine-style arms get the task's `reference/` tree,
178
- bare keeps the planted bug, and the whole copy → grade → JSONL → report
179
- loop runs in seconds. Rows are branded `"offline": true` and `report.sh`
180
- prints a SYNTHETIC banner so the numbers can never pass as behavioral
181
- results; end-to-end proven in `test.sh` plus a frozen fixture pair.
182
- - **README narrative reorder** (EN + TH): the demo GIF and the
183
- "What it prevents" table now sit directly under the intro, before
184
- Install — a newcomer sees what the pack does in 30 seconds before being
185
- asked to install anything.
186
-
187
- - **README demo GIF** — 15 seconds of the enforcement pack's real behavior:
188
- edit → `✎ unverified`, stop attempt → the rule-1 nudge, red verify →
189
- `❌ verify RED`, fix → `✅ verify`. Recorded from the checked-in
190
- `docs/assets/statusline-demo.sh`, which drives the shipped hooks in a
191
- sandbox (so the GIF cannot drift from what the scripts actually print),
192
- via the checked-in `docs/assets/demo.tape` (`vhs`). The driver script is
193
- under `test.sh`'s shellcheck net.
194
-
195
- - **`false-green` eval task** (sixth): the false-done trap — the shipped
196
- suite is green from the start while the CSV escaping bug lives outside
197
- its coverage. The untouched tree *passes its own tests* and still fails
198
- the grader (symptom probed on unseen data; bug-restored suite must go
199
- red), which is doctrine rule 1 stated as a fixture. `gamed/` (comma-only
200
- half fix) and `gamed-notest/` (correct fix, no test added) are rejected.
201
- - **`--with-lessons` eval arm** — `eval/run.sh --with-lessons` runs a third
202
- arm for tasks that ship a `lessons.md` (currently `pipeline` and
203
- `false-green`): doctrine install plus the task's ledger pre-seeded as
204
- `docs/lessons.md`, the A/B/C comparison that measures whether the
205
- learning layer pays. `report.sh` discovers arm columns from the data and
206
- renders per-arm deltas; frozen three-arm fixture added to `test.sh`.
207
- - **Per-run resource accounting** — `run.sh --out` now records duration,
208
- token usage, and cost per run (parsed fail-open from the CLI's
209
- `--output-format json` result), and `report.sh` appends per-arm resource
210
- means whenever the data is present — a pass-rate delta is only a win if
211
- the cost next to it says so.
212
- - **Community eval issue templates** — `Evaluation result` (report.sh
213
- output required, null results explicitly welcome) and `New eval task`
214
- (asks for the doctrine rule probed and the gamed tree that would cheat
215
- the grader).
216
-
217
- - **`merge-conflict` eval task** (fifth): an unresolved merge where main's
218
- bulk discount and the branch's member discount must both survive. The
219
- grader probes each feature on data the shipped tests never mention, and
220
- swaps in one-sided feature mutants to prove the worked tests actually
221
- cover both sides — `gamed/` (HEAD-only resolution, suite green) and
222
- `gamed-notests/` (correct merge, no tests added) are both rejected.
223
- - **Machine-readable closeout evidence** — `/done` step 6 now mirrors the
224
- report as a JSON block (status, verify command + exit code + decisive
225
- line, not-covered, left-out) when the result feeds CI, a PR comment, or a
226
- dashboard.
227
- - **README "What it prevents" section** (EN + TH): failure modes mapped to
228
- the shipped mechanism that catches each — no promise without a mechanism.
229
- - **SECURITY.md** — private reporting channel plus the enforced design
230
- guarantees (no network, no npm lifecycle scripts, fail-open hooks,
231
- config-dir-only writes) and the documented strict-mode env sharp edge.
232
- - **GitHub issue templates** — bug report (channel + decisive-output
233
- evidence required), feature request (doctrine-fit question), security
234
- contact link.
235
-
236
- ## [1.5.0] - 2026-08-10
237
-
238
- First version published to npm (`luciazero`); 1.4.x and below were
239
- development versions.
240
-
241
- ### Added
242
-
243
- - **Learning layer** — the pack now compounds experience across sessions,
244
- three stores, all mechanized and all pruned:
245
- - `/retro` records debugged failures to a per-repo lesson ledger
246
- (`docs/lessons.md`, fixed greppable shape: symptom → cause → proven-by →
247
- fix) and repo-independent lessons to `luciazero-heuristics.md` in the
248
- harness config dir (one line each, hard 100-line cap); stale entries are
249
- corrected or deleted, since a wrong lesson mis-seeds every future debug.
250
- - `/debug` seeds its hypothesis ledger from both files before inventing
251
- hypotheses — a match becomes H1 but is still verified.
252
- - The stop hook appends one line per stop outcome (`stop-clean` / `nudge` /
253
- `strict-block`) to `luciazero-stats.log` in the config dir — local only,
254
- fail-open, rotated at 500→250 lines — and `/retro` reads it to turn
255
- recurring discipline gaps into recorded lessons. This is the one
256
- documented exception to "state never leaves $TMPDIR"; the hook header
257
- says so.
258
- - Both uninstallers keep (and mention) the learned-data files.
259
- - test.sh: stats logging proven for all three outcomes + rotation +
260
- uninstall survival, learning-layer wiring greps on both skills, and the
261
- whole run now exports a sandbox `CLAUDE_CONFIG_DIR` so no test can ever
262
- write to the real `~/.claude`. New checks red-proven by mutation.
263
-
264
- ## [1.4.1] - 2026-08-10
265
-
266
- ### Added
267
-
268
- - **Trusted publishing (OIDC)**: `release.yml` gained an `npm-publish` job —
269
- every `v*` tag now publishes to npm from GitHub Actions with provenance
270
- attestations and no token anywhere. Guards: the tag must equal the
271
- `package.json` version, and already-live versions are skipped so re-runs
272
- cannot fail. This release exists to exercise that pipeline end to end.
273
-
274
- ### Fixed
275
-
276
- - The README shipped inside the npm tarball no longer carries the
277
- "npm publish is in flight" sentence that 1.4.0 froze in.
278
-
279
- ## [1.4.0] - 2026-08-10
280
-
281
- ### Changed
282
-
283
- - **Project renamed to Luciazero** (from "agentic-engineering"). Every brand
284
- identifier moved with it: doctrine file `claude/luciazero.md` (imported as
285
- `@luciazero.md`), hooks `luciazero-verify.sh` / `luciazero-statusline.sh`,
286
- skill `/luciazero-bootstrap`, env vars `LUCIAZERO_*` (was `AGENTIC_*`),
287
- version sidecars `.luciazero-version`, CI example
288
- `examples/luciazero-ci.example.yml`, hook state dir `luciazero-verify-state`,
289
- and the settings-cleanup matchers in both uninstallers. Nothing was
290
- published under the old name, so there is no migration path to keep.
291
- Prose still uses "agentic engineer(ing)" where it names the discipline,
292
- not the project.
293
- - **Skills moved to the repo root** (`skills/`, was `claude/skills/`) so
294
- `npx skills add <owner>/luciazero` (vercel-labs/skills) discovers them with
295
- zero registration. Installers, tests, and docs all read the new path.
296
-
297
- ### Added
298
-
299
- - **Claude Code plugin packaging**: `.claude-plugin/plugin.json` +
300
- `.claude-plugin/marketplace.json` make the repo installable as a plugin
301
- from its own single-plugin marketplace (`/plugin marketplace add
302
- <owner>/luciazero` → `/plugin install luciazero@luciazero`); `claude plugin
303
- validate` passes. `claude/hooks/hooks.json` wires the verify hooks via
304
- `${CLAUDE_PLUGIN_ROOT}`, and a new `doctrine` subcommand of
305
- `luciazero-verify.sh` loads the doctrine as SessionStart context — plugins
306
- cannot add a CLAUDE.md import line — with a guard that stays silent when a
307
- classic install exists, so the doctrine never loads twice. Honest limits
308
- documented: no statusline via plugins; pick one channel so hooks are not
309
- wired twice.
310
- - **npm wrapper** (`package.json` + `bin/luciazero.js`): `npx luciazero`
311
- routes to the bundled installers (`codex`, `uninstall`, `uninstall-codex`
312
- subcommands; flags pass through). No lifecycle scripts, ever — test.sh
313
- fails if one appears, matching npm v12's default block.
314
- - **Lucia mascot** in both READMEs, cropped from the project's character
315
- sheet (`docs/assets/lucia*.png`): plushie-hug under the title, laptop pose
316
- at the eval paragraph, and the fist-up pose celebrating
317
- `PASS all checks green` in Development.
318
- - **README rewrite (both languages)**: install-channels-first — plugin
319
- (recommended) and `npx skills add` lead, classic `git clone` demoted to the
320
- reference channel; sections condensed; the stale "Why not a Claude Code
321
- plugin" design note replaced with "How the plugin squares with this"; new
322
- "Lucia family & support" section (Lucia Discord bot + donate link).
323
- A 2-lens verification pass (bilingual fidelity + truth-to-code) confirmed
324
- the new claims and caught 4 wording issues, all fixed.
325
- - **docs/publishing.md**: dependency-ordered release checklist (GitHub →
326
- plugin directory submission → npm trusted publishing → awesome-claude-code),
327
- with the channel-honesty note that only the classic installer carries the
328
- statusline and CLAUDE.md import.
329
- - test.sh grew five gates for the above: manifest validity + version sync
330
- across CHANGELOG/plugin.json/package.json, doctrine-mode behavior (emits
331
- once, never twice), npm payload completeness + lifecycle-script ban
332
- (with a live `--status` routing probe when node is present), the plugin
333
- channel dedupe, and the installers' unknown-option rejection. All five
334
- proven red by mutation before being trusted.
335
-
336
- ### Fixed (post-review of the rename/packaging wave; 11 confirmed findings)
337
-
338
- - `install-codex.sh`, `uninstall.sh`, and `uninstall-codex.sh` now reject
339
- unknown options — previously `npx luciazero codex --status` silently
340
- performed a FULL install instead of a status check, and stray flags to the
341
- uninstallers were swallowed.
342
- - Plugin doctrine mode no longer needs python3 or stdin: it is handled before
343
- the script's shared setup, so machines without python3 (where every other
344
- mode fails open to doing nothing) still load the doctrine. It also survives
345
- an unset `HOME` (was an `set -u` abort violating the fail-open contract).
346
- - Running any hook mode by hand from a terminal no longer hangs waiting for
347
- stdin EOF.
348
- - Plugin + `install.sh --with-hooks` double-install: the plugin's hooks.json
349
- now invokes every mode with `LUCIAZERO_CHANNEL=plugin`, and the hook stands
350
- down when classic wiring exists in settings.json — the stop nudge can no
351
- longer double-fire, and a strict verify command can no longer run twice
352
- concurrently against the same repo.
353
- - The debug and bootstrap skills no longer hardcode classic-install paths
354
- (`~/.claude/...`) that do not exist under the plugin / `npx skills`
355
- channels.
356
- - Release procedure docs caught up with the version-sync gate: CONTRIBUTING's
357
- Releasing step and docs/publishing.md now both say to bump plugin.json +
358
- package.json together with the CHANGELOG heading (following the old steps
359
- verbatim would have produced a red release workflow), and publishing.md no
360
- longer hardcodes tagging the already-released v1.3.0.
361
- - docs/comparison.md no longer lists "plugin marketplace" as something
362
- superpowers has and we don't (this repo is now its own single-plugin
363
- marketplace; theirs remains a multi-plugin ecosystem).
364
-
365
- - **Strict verify gate** (opt-in on top of the opt-in enforcement pack): set
366
- `LUCIAZERO_STRICT_VERIFY_CMD` in your *personal* settings and the Stop hook
367
- actually runs that command (fast-pathing when the tracked state is already
368
- green after the last edit) and blocks a red stop with the failing output
369
- quoted. Hard timeout (`LUCIAZERO_STRICT_TIMEOUT`, default 120s); every
370
- internal error degrades to the ordinary fail-open nudge. The variable
371
- belongs in personal settings only; the hook cannot verify which settings
372
- scope set it (a committed `.claude/settings.json` env block reaches it
373
- too), and the docs say so plainly — never commit it, and treat a repo
374
- that ships it as hostile. Documented honestly as a speed bump, not a
375
- wall: a blocked stop's continuation is never re-blocked.
376
- - **Exact-match verify tracking**: `LUCIAZERO_VERIFY_CMD` switches the Bash
377
- tracker from the broad regex to prefix matching, closing a real
378
- false-green — `cat test.sh` or `grep pytest README` no longer count as a
379
- verify run. `/luciazero-bootstrap` Phase 2 now offers (ask-first) to record
380
- the established command in the repo's `.claude/settings.local.json`.
381
- - **SessionStart handoff pointer**: a `session` hook subcommand emits one
382
- context line when the project has a `HANDOFF.md` capsule — age included,
383
- stale warning past `LUCIAZERO_HANDOFF_STALE_DAYS` (default 7), silent and
384
- zero-cost when there is none, pointer only (never the contents).
385
- - **`revert-probe.sh`** (ships inside the done skill, works on both
386
- harnesses): the mechanical form of "would the new tests fail if the change
387
- were reverted?" — checks the pre-change code into a throwaway git
388
- worktree, overlays only the changed test files, runs the verify command
389
- there and inverts the result. Exit 0 tests bite / 1 vacuous or no test
390
- changes / 2 unassessable; never touches the caller's tree. `/done` and
391
- `/debug` reference it.
392
- - **Three new eval tasks**, each probing a different doctrine rule:
393
- `red-suite` (correct-but-red suite; the lazy fix is bending the tests to
394
- the bug — caught by replaying the fixture's pristine tests against the
395
- worked code), `flaky-report` (hash-seed-dependent output; graded
396
- deterministically via a `PYTHONHASHSEED` 0–9 sweep), `pipeline` (bug in
397
- the parser, symptom two modules away; graded by diff *locality* — the
398
- untouched modules must stay AST-identical).
399
- - **`gamed*/` cheat fixtures + grader auto-discovery**: every task now ships
400
- one or more hand-built cheat trees its grader must reject — including
401
- hardcoded-lookup (`red-suite/gamed-hardcode/`) and hardcoded-output
402
- (`flaky-report/gamed-hardcode/`) variants killed by unseen-data criteria —
403
- and `test.sh` auto-discovers `eval/tasks/*/` so no task can ship without
404
- proving its grader goes red, green, and anti-gamed (a missing `gamed/` is
405
- itself a red build) and speaks the new machine-readable
406
- `CRIT <id> pass|fail` / `SCORE n/m` output contract.
407
- - **`eval/run.sh --runs N --out results.jsonl` + `eval/report.sh`**: repeat
408
- runs, record per-criterion results as JSONL, and render the doctrine-vs-
409
- bare pass-*rate* table the honesty box has always prescribed — with n and
410
- a low-n warning printed unconditionally. `report.sh` is byte-compared
411
- against a frozen fixture in CI and rejects malformed input.
412
- - **`install.sh --status`**: read-only health check of an existing install —
413
- every piece listed, hook wiring verified in `settings.json` (the hooks
414
- fail open, so a broken install was previously silent), version compared,
415
- non-zero exit when a core piece is missing. Plus a version sidecar
416
- (`.luciazero-version`, both harnesses) and a documented update
417
- path in the README.
418
- - **`demo.sh`**: scaffolds the slugify planted-bug fixture into a throwaway
419
- git repo, prints the bug report and the exact commands — fix it in your
420
- own Claude session, then score the tree with the offline grader. Never
421
- invokes `claude` itself; refuses to scaffold inside the repo.
422
- - **`docs/comparison.md`**: dated, sourced, deliberately two-sided
423
- comparison against superpowers, SuperClaude, proof-loop, orchestrator
424
- runtimes, template catalogs, and the harness built-ins.
425
- - README: 60-second quickstart, a "What it looks like" section showing the
426
- actual statusline/nudge/strict-gate output (captured, not composed), and
427
- an Updating section.
428
- - **`README.th.md`** — full Thai translation of the README, replacing the
429
- abridged Thai section; English stays the default, both files cross-link,
430
- and `test.sh` trips when the section structures drift apart.
431
-
432
- - `/done` skill — closeout ritual before declaring a non-trivial task
433
- complete: full-tier verify with the decisive line quoted, a skeptic pass
434
- over the final diff, an independent adversarial review when the diff
435
- earns it, an explicit scope check naming anything left out, and a fixed
436
- report format. Doctrine rule 1 now points to it.
437
- - `/handoff` skill — transient state capsule (`HANDOFF.md`) for resuming
438
- unfinished work across sessions, machines, or harnesses: goal, verified
439
- state, one literal next command, open and refuted hypotheses, landmines.
440
- Consumed and deleted by the reader; `/retro` stays the home of permanent
441
- lessons.
442
- - `/experiment` skill — measured-change protocol for optimization work:
443
- metric and win threshold defined before any change, multi-run baseline,
444
- one variable per experiment, verdicts (including null results) recorded
445
- to `docs/experiments.md`, losers reverted immediately.
446
- - Enforcement pack (`./install.sh --with-hooks`, Claude Code only,
447
- requires python3): a verify-tracking hook pair plus statusline —
448
- PostToolUse hooks record edits and verify-ish Bash runs per project, a
449
- Stop hook nudges once (fails open, never loops) when a session ends
450
- with unverified edits, and the statusline shows `model | branch |
451
- ✅ verify 3m` / `❌ verify RED` / `✎ unverified` at a glance. The
452
- settings.json merge is additive, idempotent, backed up, respects an
453
- existing custom statusLine, and `uninstall.sh` removes exactly our
454
- entries while preserving everything else.
455
- - `examples/luciazero-ci.example.yml` — inert, REPLACE-ME-gated GitHub
456
- Actions template: on CI failure, an agent diagnoses the root cause from
457
- the failing logs (hypothesis + evidence line, logs treated as untrusted
458
- input) and posts a size-capped PR comment. Diagnosis only — it cannot
459
- push or edit code (`contents: read`, tool allowlist without Bash,
460
- `persist-credentials: false`); its single write scope is
461
- `pull-requests: write` for the comment. Fork-guarded secrets, no
462
- auto-fix.
463
- - `eval/` — A/B harness measuring whether the doctrine changes agent
464
- behavior: planted-bug task fixtures graded offline by behavioral
465
- criteria (bug actually fixed, a regression test that goes red when the
466
- buggy implementation is restored, no weakened checks). `eval/run.sh`
467
- runs both arms (doctrine vs bare config) and costs API money, so it is
468
- manual; `test.sh` verifies the graders themselves can go both red and
469
- green, offline.
470
- - `test.sh` now also exercises the enforcement-pack hook state machine,
471
- the `--with-hooks` install/uninstall cycle against a settings.json with
472
- pre-existing user content, the eval graders' red/green behavior, and the
473
- inertness of the luciazero-ci example.
474
-
475
- - `/debug` skill — hypothesis-driven debugging procedure, the on-demand
476
- expansion of the doctrine's hypothesis rule: deterministic reproduction
477
- first, minimized repro, a visible hypothesis ledger (run the refuting
478
- observation, not the edit), one variable per iteration with failed fixes
479
- reverted, close-out via a regression test red before the fix and green
480
- after. Installed by both harness installers.
481
- - `luciazero-bootstrap` now bundles `scripts/detect.sh` — a read-only,
482
- dependency-free evidence scan (bash plus standard tools; python3 to
483
- parse `package.json` when available, `sed` fallback) covering docs,
484
- manifests, script/target names, CI `run:` lines, test dirs, monorepo
485
- markers, and git status, replacing a dozen manual reads in Phase 1. It surfaces candidates only; the agent still decides.
486
- Ships to both harnesses via the existing skill copy.
487
- - Bootstrap Phase 2 hardening: verify must run unattended (no watch or
488
- interactive modes), the suite is timed once so the measurement (not a
489
- guess) decides one tier or two, fast-tier output should be near-silent,
490
- and monorepos scope the fast tier to the package being changed.
491
- - Bootstrap Phase 6 rewrite: run the fast tier twice to catch flakes,
492
- break a line a smoke test actually *covers* (breaking an uncovered line
493
- proves nothing), restore via `git checkout`/`git stash`; Phase 1 now
494
- reports git-repo status and proposes `git init` (ask first) for
495
- unversioned dirs.
496
- - `/retro` routing gate: lessons true for anyone who clones the repo go to
497
- committed notes; machine-local or personal facts go to the harness's
498
- memory system (Claude Code's per-project `memory/` dir + `MEMORY.md`
499
- index) and are never committed; on Codex (no memory system) only the
500
- machine-independent generalization is kept — an honest gap beats a note
501
- no harness loads.
502
- - `test.sh` now enforces the doctrine's word-count budget (≤420 words) and
503
- platform-neutral vocabulary, smoke-runs `detect.sh` against the repo
504
- itself, and covers the new skill and script in both sandbox cycles.
505
- - Example settings: inert check-suppression guard hook (blocks edits that
506
- add `noqa`/`ts-ignore`/`.skip(`-style markers, mechanizing "never weaken
507
- a check"), and the derived-files hook example now explains scoping by
508
- `tool_input.file_path` so it does not run on every edit.
509
- - `reviewer` agent: `model: inherit` frontmatter — an adversarial reviewer
510
- on a weaker model than the author defeats its purpose. The Codex
511
- transform drops `model:` alongside `tools:`.
512
-
513
- ### Changed
514
-
515
- - **Doctrine cut from 15 rules to 9** (568 → ~415 words). Removed
516
- outright — each relies on a behavior 2026 harnesses enforce by default;
517
- if a harness regresses, restore from here: style matching (old R7
518
- tail), read-before-overwrite (old R8 tail — mechanically enforced by
519
- Write tools), wide-read delegation (old R10 — also impossible on
520
- Codex). Folded into surviving rules, not cut: faithful run reporting
521
- (old R3 → one clause in new R1), the loop itself (old R5 → preamble),
522
- read-project-notes-first (old R12 → new R8), routine-work-without-
523
- blocking (old R13 → new R9), whole-scope completion and honest handback
524
- (old R15 / R5 tail → closing clause of new R9). The stop-and-ask list
525
- survives as new R9.
526
- - Doctrine rule 7 routes risky/wide diffs through the harness's built-in
527
- review command when one exists (Claude Code: `/code-review`), with the
528
- shipped `reviewer` agent as the portable fallback and the only reviewer
529
- on Codex.
530
- - Doctrine and skills are now platform-neutral: "notes file
531
- (`CLAUDE.md` / `AGENTS.md`)" instead of assuming one harness; bootstrap
532
- Phase 4 marks hooks/settings/`/fewer-permission-prompts` as Claude-only
533
- and tells Codex sessions to encode the same guardrails in `AGENTS.md`;
534
- Phase 5 retitled "Project notes file".
535
- - Bootstrap Phase 1 no longer early-stops at possibly-stale docs: sources
536
- are reordered CI-first and doc-claimed commands are cross-checked
537
- against CI; a docs/CI mismatch is itself a finding.
538
- - README: removed the free-floating version line (CHANGELOG is the version
539
- source of truth), corrected the `SessionStart` design note (Claude Code
540
- re-injects `CLAUDE.md` after compaction; the real anti-drift lever is
541
- doctrine size), and recorded the decision against plugin packaging.
542
-
543
- ### Fixed
544
-
545
- - The slugify grader could be gamed for a perfect score: keeping the four
546
- original test *names* with `pass` bodies plus one real regression test
547
- passed every criterion. A new contract-mutant criterion (the worked suite
548
- must go red against an implementation that breaks the original
549
- leading/trailing-separator contract while handling unicode correctly)
550
- closes it; the exact cheat is checked in as `gamed/` and CI proves the
551
- grader rejects it.
552
- - The verify-tracking hook counted *reading* the test file (`cat test.sh`,
553
- `grep pytest README`) as a verify run, flipping the statusline green and
554
- disarming the stop nudge with no test run — fixed opt-in via
555
- `LUCIAZERO_VERIFY_CMD` exact matching (the broad regex remains the default).
556
- - The example check-suppression guard blocked edits *near* a pre-existing
557
- suppression marker (it regexed the whole tool input, so an untouched
558
- `noqa` in `old_string` triggered it). Now diff-aware: it compares marker
559
- counts between new and old text (`old_string` for Edit, the on-disk file
560
- for Write) and blocks only when an edit *adds* a marker.
561
- - `uninstall.sh` no longer aborts halfway (unguarded `grep` no-match under
562
- `set -e`) when `CLAUDE.md` contains only the import line — exactly the
563
- state `install.sh` creates for a user with no prior `CLAUDE.md`. It now
564
- also removes an empty `CLAUDE.md` instead of leaving a zero-line file.
565
- Regression-tested by a fresh-user install→uninstall cycle in `test.sh`.
566
- - `install-codex.sh` reinstalls no longer grow `AGENTS.md` by one blank
567
- line per run; a reinstall is now byte-identical (asserted in `test.sh`).
568
- - Backup names (`*.bak.<timestamp>`) are collision-proof in all four
569
- install/uninstall scripts — two runs in the same second previously
570
- overwrote the earlier backup, destroying the pristine pre-install copy.
571
-
572
- ## [1.3.0] - 2026-08-07
573
-
574
- ### Added
575
-
576
- - OpenAI Codex CLI support: `install-codex.sh` / `uninstall-codex.sh`.
577
- Doctrine lands as a marker-delimited block in `~/.codex/AGENTS.md`;
578
- `luciazero-bootstrap` and `retro` copy as-is (Codex reads the same
579
- `SKILL.md` format); the `reviewer` agent ships as a Codex skill with the
580
- Claude-only `tools:` frontmatter line dropped. Honors `CODEX_HOME`,
581
- backs up `AGENTS.md`, idempotent, converts from the `claude/` sources at
582
- install time so nothing is duplicated in the repo.
583
- - `test.sh` covers the Codex cycle in its own sandbox (marker-block
584
- idempotency, skill installs, `tools:` line stripped, uninstall restores
585
- pre-existing `AGENTS.md` content).
586
-
587
- ## [1.2.0] - 2026-08-07
588
-
589
- ### Added
590
-
591
- - Doctrine rule 6 — debugging starts with a hypothesis and the command
592
- that would confirm or refute it, before any edit.
593
- - Doctrine rule 9 — review the final diff as a skeptic before declaring
594
- done; risky diffs get an independent reviewer agent. (15 rules total.)
595
- - `/retro` skill — harvest session lessons (null results, footguns,
596
- environment quirks) into the project's `CLAUDE.md`/`docs/`, deduping
597
- against and correcting existing notes.
598
- - `agents/reviewer.md` — read-only adversarial reviewer subagent:
599
- severity-tagged findings, verified against source, `No findings.` over
600
- invented ones.
601
- - Bootstrap Phase 2 — two-tier verify guidance: fast `verify` every loop
602
- iteration, `verify-full` before declaring done; single tier for small
603
- repos.
604
-
605
- ### Changed
606
-
607
- - `install.sh`/`uninstall.sh`/`test.sh` cover the new skill and agent;
608
- installer backs up a pre-existing customized `agents/reviewer.md`
609
- before overwriting.
610
-
611
- ## [1.1.0] - 2026-08-07
612
-
613
- ### Added
614
-
615
- - Doctrine rule 12 — **stop and ask before high-stakes moves, and ask
616
- clearly**: deleting data, deploying or touching production,
617
- force-pushing, changing a public API/contract, spending real money, or
618
- leaving the agreed scope require a decidable question (what, why,
619
- options, recommendation) before proceeding. "Finish the whole scope"
620
- renumbered to 13.
621
-
622
- ## [1.0.0] - 2026-08-07
623
-
624
- ### Added
625
-
626
- - 12-rule luciazero doctrine (`claude/luciazero.md`),
627
- loaded in every session via an `@luciazero.md` import in the
628
- global `~/.claude/CLAUDE.md`.
629
- - `/luciazero-bootstrap` skill — six-phase, language-agnostic procedure that
630
- makes a repository agent-ready (detect commands, establish a verify
631
- command, smoke tests, guardrails, project `CLAUDE.md`, prove verify can
632
- go red).
633
- - `install.sh` / `uninstall.sh` — idempotent, back up `CLAUDE.md` before
634
- editing, never write outside the Claude config dir, honor
635
- `CLAUDE_CONFIG_DIR`.
636
- - Inert per-repo settings example
637
- (`examples/project-settings.example.json`): permission allowlist,
638
- secret-read denies, disabled hook templates.
639
- - `test.sh` verify command; GitHub Actions CI on every push and
640
- zip-building release workflow on version tags.
641
- - MIT license.