luciazero 1.5.0 → 2.0.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 CHANGED
@@ -7,18 +7,186 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [1.5.0] - 2026-08-10
10
+ ## [2.0.1] - 2026-08-13
11
+
12
+ ### Added
13
+
14
+ - **Explicit, channel-aware updates.** `npx luciazero@latest check-update`
15
+ performs a read-only, five-second npm registry check only when invoked;
16
+ `npx luciazero@latest update` detects classic Claude, its hook mode, and
17
+ Codex, then refreshes every detected install through the existing audited
18
+ installers. It refuses to create a fresh install, downgrade a recognized
19
+ newer one, or trust a malformed version sidecar. Legacy installs without the
20
+ sidecar remain updatable. Classic doctrine customization now receives the
21
+ same managed-snapshot backup protection as skills and agents.
22
+ Plugin and skills-only update commands, Claude plugin auto-update, and GitHub
23
+ release notifications are documented separately in both READMEs.
24
+
25
+ ### Changed
26
+
27
+ - The release workflow uses the runner's GitHub CLI instead of a Node 20-based
28
+ release action. Re-runs replace the existing zip without recreating the
29
+ release, and GitHub Actions no longer emits the deprecated-runtime warning.
30
+
31
+ ## [2.0.0] - 2026-08-13
11
32
 
12
33
  ### Changed
13
34
 
14
- - **Project renamed to Luciazero** (from "lucidone", hours after 1.4.1, before
15
- any adoption) the mascot's name belongs in the project's name, and
16
- Lucia + exit 0 says what the doctrine means by done. Every identifier moved:
17
- files, `LUCIAZERO_*` env vars, hooks, markers, sidecars, npm/plugin names.
18
- Versions 1.4.0–1.4.1 shipped to npm as `lucidone` and were unpublished
19
- within npm's 72-hour window; GitHub tags v1.4.0/v1.4.1 keep the old-name
20
- trees for the record. Earlier CHANGELOG entries read with the new name
21
- applied retroactively.
35
+ - The canonical Sonnet result is explicitly preliminary (`+31pp`, n=4–5).
36
+ The historical `+37pp` statement is retired because its eight replacement
37
+ raw rows could not be recovered.
38
+ - `eval/report.sh` rejects mixed campaigns/commits/seeds, changed fixture
39
+ hashes, duplicate invocation IDs, and inconsistent pair order. Published
40
+ evidence also enforces registered task/arm/row/invalid/model expectations,
41
+ and discloses Haiku's incomplete per-row model provenance.
42
+ - Eval tasks may provide deterministic offline setup before either arm. Provider
43
+ transcripts now live outside worked trees so they cannot alter Git status,
44
+ repository fingerprints, or final-tree grading.
45
+ - Relay fingerprints encode untracked special files without opening them, so a
46
+ FIFO, socket, or device cannot block inspection or trigger device I/O.
47
+ - GitHub workflows use the Node 24-based `actions/checkout@v5` and
48
+ `actions/setup-node@v5` runtimes.
49
+ - **Breaking: `/handoff` is now `/lucia-relay`.** The branded name avoids
50
+ collisions with generic handoff skills. Installs remove an untouched v1.5
51
+ copy but preserve and warn about customized copies. Relay state is now a
52
+ validated `LUCIA_RELAY.json` manifest plus a generated human view, with a
53
+ repository fingerprint, verification evidence, negative knowledge,
54
+ cross-session/cross-agent routing, drift inspection, and explicit consume.
55
+ - **Risk-routed review.** The single portable reviewer now accepts `general`,
56
+ `security`, and `contract` focus modes, reads callers/consumers, and uses one
57
+ blocker/major/minor policy. `/done` requests separate focused passes when a
58
+ diff crosses both security and contract boundaries.
59
+ - **Smart verification is repo-owned.** Monorepos create `verify-changed` from
60
+ their native task graph and keep `verify-full` for closeout. The global hook
61
+ never guesses dependency impact from path prefixes.
62
+ - **Classic and Codex installs track component ownership.** Exact hidden
63
+ snapshots distinguish Luciazero-managed skills/agents from same-name user or
64
+ third-party components. Updates back up collisions/customizations, and
65
+ uninstall removes only an unchanged managed copy.
66
+
67
+ ### Added
68
+
69
+ - Auditable benchmark evidence: canonical Claude raw JSONL, a SHA-256 campaign
70
+ registry, generated README/benchmark tables, and a CI drift check.
71
+ - Result schema 2 records campaign, pair, invocation, repository, fixture,
72
+ prompt, platform, and arm-order metadata. Seeded arm randomization reduces
73
+ fixed-order bias without making campaigns irreproducible.
74
+ - Strict shared result validation rejects unsupported schemas and mistyped
75
+ booleans, criteria, metrics, timestamps, platform, and campaign metadata.
76
+ Output-aware `--resume` fills interrupted pairs without rerunning completed
77
+ invocation IDs; `--run-offset` extends completed batches.
78
+ - Three zero-quota candidate eval tasks cover archive extraction security,
79
+ lossless atomic schema migration, and multi-page cursor integration. Each
80
+ grader proves reference/project/anti-gamed behavior offline.
81
+ - **`relay-transfer` protocol eval** grades portable state, an exact next edit,
82
+ verification evidence, negative knowledge, scope preservation, and a current
83
+ repository fingerprint. CI proves its 6/6 reference and rejects generic
84
+ prose plus a content-complete stale relay without spending model quota.
85
+ - **Lucia Relay demo** drives the shipped producer/receiver implementation in
86
+ a temporary Git repository: render, validate, detect drift, re-run evidence,
87
+ and explicitly consume. The checked-in GIF is generated from the same script
88
+ exercised by CI.
89
+ - **Central component catalogs** drive classic/Codex install, status,
90
+ uninstall, and inventory tests, so a new skill or agent cannot silently ship
91
+ through only one channel.
92
+ - **`/plan`** defines falsifiable acceptance signals and reversible steps,
93
+ while pausing for approval only on ambiguity, high stakes, destructive work,
94
+ public-contract choices, or scope changes.
95
+ - **`/bisect` + `safe-bisect.sh`** locate the first bad commit in a detached
96
+ temporary worktree, repeat endpoints to catch flakes, preserve exit 125
97
+ skips, distinguish missing commands, and clean every exit path.
98
+ - **`npx luciazero discipline` + `/discipline-report`** analyze schema-v2
99
+ local JSONL outcomes with day/project filters and JSON output. The hook logs
100
+ a privacy-preserving project hash and verify mode; legacy records remain
101
+ readable and recommendations distinguish observations from likely causes.
102
+ - **`/lucia-relay` carries memory pointers** — the `Read first`
103
+ section quotes the `docs/lessons.md` entries relevant to the unfinished
104
+ work (a selection, never a copy — the ledger travels with the repo) and
105
+ copies applicable machine-local `luciazero-heuristics.md` entries
106
+ verbatim, since the relay is the only way those cross machines. The
107
+ consume protocol tells the reader to follow the pointers before touching
108
+ code and to adopt carried heuristics that earn their keep.
109
+
110
+ - **`eval/run.sh --use-login`** — run the real eval on an existing Claude
111
+ subscription (Pro/Max) instead of API dollars: seeds each per-run sandbox
112
+ config dir with this machine's login state — `~/.claude.json`, plus
113
+ OAuth tokens from `.credentials.json` (Linux) or a Keychain export
114
+ (macOS). The copy lives only inside the mktemp sandbox and is deleted
115
+ with it. Fail-soft by
116
+ design: if the seed does not authenticate, `check-result.sh` marks the
117
+ arm INVALID and nothing is spent. Plumbing (seed per arm, warn on missing
118
+ login state) is proven offline in `test.sh`.
119
+
120
+ - **`eval/check-result.sh`** — a zero exit code no longer proves the agent
121
+ ran: the CLI has wrapped a `Not logged in` error in subtype `"success"`
122
+ (observed 2026-08-11, caught free by a 1-run smoke). The guard inspects
123
+ the result payload (`is_error`, `terminal_reason: api_error`, login
124
+ errors) and `run.sh` books a refuted arm as INVALID with the reason
125
+ quoted; every accept/reject path is fixture-proven in `test.sh`.
126
+ - **`eval/run.sh --offline`** — synthetic smoke mode: no `claude` CLI, no
127
+ API key, zero cost. Doctrine-style arms get the task's `reference/` tree,
128
+ bare keeps the planted bug, and the whole copy → grade → JSONL → report
129
+ loop runs in seconds. Rows are branded `"offline": true` and `report.sh`
130
+ prints a SYNTHETIC banner so the numbers can never pass as behavioral
131
+ results; end-to-end proven in `test.sh` plus a frozen fixture pair.
132
+ - **README narrative reorder** (EN + TH): the demo GIF and the
133
+ "What it prevents" table now sit directly under the intro, before
134
+ Install — a newcomer sees what the pack does in 30 seconds before being
135
+ asked to install anything.
136
+
137
+ - **README demo GIF** — 15 seconds of the enforcement pack's real behavior:
138
+ edit → `✎ unverified`, stop attempt → the rule-1 nudge, red verify →
139
+ `❌ verify RED`, fix → `✅ verify`. Recorded from the checked-in
140
+ `docs/assets/statusline-demo.sh`, which drives the shipped hooks in a
141
+ sandbox (so the GIF cannot drift from what the scripts actually print),
142
+ via the checked-in `docs/assets/demo.tape` (`vhs`). The driver script is
143
+ under `test.sh`'s shellcheck net.
144
+
145
+ - **`false-green` eval task** (sixth): the false-done trap — the shipped
146
+ suite is green from the start while the CSV escaping bug lives outside
147
+ its coverage. The untouched tree *passes its own tests* and still fails
148
+ the grader (symptom probed on unseen data; bug-restored suite must go
149
+ red), which is doctrine rule 1 stated as a fixture. `gamed/` (comma-only
150
+ half fix) and `gamed-notest/` (correct fix, no test added) are rejected.
151
+ - **`--with-lessons` eval arm** — `eval/run.sh --with-lessons` runs a third
152
+ arm for tasks that ship a `lessons.md` (currently `pipeline` and
153
+ `false-green`): doctrine install plus the task's ledger pre-seeded as
154
+ `docs/lessons.md`, the A/B/C comparison that measures whether the
155
+ learning layer pays. `report.sh` discovers arm columns from the data and
156
+ renders per-arm deltas; frozen three-arm fixture added to `test.sh`.
157
+ - **Per-run resource accounting** — `run.sh --out` now records duration,
158
+ token usage, and cost per run (parsed fail-open from the CLI's
159
+ `--output-format json` result), and `report.sh` appends per-arm resource
160
+ means whenever the data is present — a pass-rate delta is only a win if
161
+ the cost next to it says so.
162
+ - **Community eval issue templates** — `Evaluation result` (report.sh
163
+ output required, null results explicitly welcome) and `New eval task`
164
+ (asks for the doctrine rule probed and the gamed tree that would cheat
165
+ the grader).
166
+
167
+ - **`merge-conflict` eval task** (fifth): an unresolved merge where main's
168
+ bulk discount and the branch's member discount must both survive. The
169
+ grader probes each feature on data the shipped tests never mention, and
170
+ swaps in one-sided feature mutants to prove the worked tests actually
171
+ cover both sides — `gamed/` (HEAD-only resolution, suite green) and
172
+ `gamed-notests/` (correct merge, no tests added) are both rejected.
173
+ - **Machine-readable closeout evidence** — `/done` step 6 now mirrors the
174
+ report as a JSON block (status, verify command + exit code + decisive
175
+ line, not-covered, left-out) when the result feeds CI, a PR comment, or a
176
+ dashboard.
177
+ - **README "What it prevents" section** (EN + TH): failure modes mapped to
178
+ the shipped mechanism that catches each — no promise without a mechanism.
179
+ - **SECURITY.md** — private reporting channel plus the enforced design
180
+ guarantees (no network, no npm lifecycle scripts, fail-open hooks,
181
+ config-dir-only writes) and the documented strict-mode env sharp edge.
182
+ - **GitHub issue templates** — bug report (channel + decisive-output
183
+ evidence required), feature request (doctrine-fit question), security
184
+ contact link.
185
+
186
+ ## [1.5.0] - 2026-08-10
187
+
188
+ First version published to npm (`luciazero`); 1.4.x and below were
189
+ development versions.
22
190
 
23
191
  ### Added
24
192
 
package/README.md CHANGED
@@ -7,208 +7,231 @@
7
7
  [![license](https://img.shields.io/github/license/ohm41321/luciazero)](LICENSE)
8
8
 
9
9
  <p align="center">
10
- <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia.png" width="300" alt="Lucia — Luciazero's mascot — hugging her cat plushie">
10
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia.png" width="280" alt="Lucia — Luciazero's mascot">
11
11
  </p>
12
12
 
13
- Luciazero makes a coding agent run its own `plan → change → verify → fix` loop instead of handing back unverified work. Its first rule is not about prompting:
13
+ Luciazero makes coding agents run a `plan → change → verify → fix` loop instead
14
+ of handing back work they merely believe is finished.
14
15
 
15
- > Done is proven by a command, not by my judgment. If no verification command exists, that is the first bug.
16
+ > Done is proven by a command, not by my judgment. If no verification command
17
+ > exists, that is the first bug.
16
18
 
17
- Everything in this repo — a 9-rule doctrine, six skills, an adversarial reviewer agent, enforcement hooks, an eval harness — exists to make that rule hold without a human in the loop.
19
+ It ships a compact [9-rule doctrine](claude/luciazero.md), 9 on-demand skills,
20
+ verification hooks, a risk-routed reviewer, and an eval harness. It is a
21
+ discipline layer, not an agent runtime or overnight orchestrator.
18
22
 
19
- ## Install
20
-
21
- **Claude Code — plugin (recommended).** One install carries the six skills, the `reviewer` agent, the verify-tracking hooks, and the doctrine:
22
-
23
- ```
24
- /plugin marketplace add ohm41321/luciazero
25
- /plugin install luciazero@luciazero
26
- ```
23
+ ## See it in 15 seconds
27
24
 
28
- Then run `/luciazero:luciazero-bootstrap` in any repository (plugin skills are namespaced: `/luciazero:done`, `/luciazero:debug`, …). Honest print: installing the plugin is what enables its hooks — that install step *is* the opt-in; the doctrine loads via a `SessionStart` hook because plugins cannot add a `CLAUDE.md` import line (same word-ceiling-capped text, and it stays silent when a classic install exists, so it never loads twice); and there is no statusline, because Claude Code does not let plugins set `statusLine`.
25
+ This GIF is driven by the shipped hooks, not a mockup:
29
26
 
30
- **Any agent — skills only.** Via [vercel-labs/skills](https://github.com/vercel-labs/skills), into Claude Code, Codex, Cursor, and 70+ others. No doctrine, no reviewer agent, no hooks:
27
+ <p align="center">
28
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/statusline-demo.gif" width="720" alt="Edit becomes unverified, a red check stays red, and a successful verify turns green">
29
+ </p>
31
30
 
32
- ```
33
- npx skills add ohm41321/luciazero
31
+ ```text
32
+ unverified → edits happened after the last check
33
+ ❌ verify RED → the latest check failed
34
+ ✅ verify 3m → the latest check passed three minutes ago
34
35
  ```
35
36
 
36
- **Classic install.** The reference channel — the only one with the statusline, the `CLAUDE.md` import, a `--status` health check, and the Codex CLI installer. Details in the next sections:
37
+ ## What it prevents
37
38
 
38
- ```bash
39
- npx luciazero # Claude Code (--with-hooks for the enforcement pack, --status)
40
- npx luciazero codex # Codex CLI (npx luciazero uninstall to remove)
41
- ```
39
+ | Failure mode | Mechanism |
40
+ |---|---|
41
+ | “Done” without running a check | Stop-hook nudge; optional strict gate blocks a red stop |
42
+ | `cat test.sh` counted as testing | Exact `LUCIAZERO_VERIFY_CMD` matching |
43
+ | Tests weakened to reach green | Doctrine rule 3 + check-suppression guard |
44
+ | New tests that pass without the fix | `revert-probe.sh` runs them against the old code |
45
+ | Scope silently dropped | `/done` requires every item delivered or named as left out |
46
+ | The same dead end repeated later | `/retro` records it; `/debug` reads it first |
47
+ | Context lost between agents | `/lucia-relay` transfers evidence, next action, and negative knowledge |
42
48
 
43
- `npx luciazero` is a thin wrapper with zero lifecycle scripts — nothing runs at npm install time (`test.sh` enforces that); it just launches the same audited bash installers you would get from `git clone https://github.com/ohm41321/luciazero.git && ./install.sh`. Pick **one** channel — plugin or classic — so the hooks are never wired twice. Want proof before installing anything? `./demo.sh` scaffolds a planted-bug repo you fix in your own session and score with an offline grader.
49
+ Mechanical guarantees run in `test.sh`; behavioral claims are measured by the
50
+ [eval harness](eval/README.md).
44
51
 
45
- ## After installing: which skill when
52
+ ## Carry unfinished work across agents
46
53
 
47
- Nothing to memorize — the doctrine and the hooks work by themselves. Skills are for specific moments, and the first move in any repository is `/luciazero-bootstrap`, once, so a verify command exists for everything else to lean on. (Plugin installs prefix the names: `/luciazero:done`, `/luciazero:debug`, …)
54
+ `/lucia-relay` transfers decisions and evidence instead of dumping a chat
55
+ transcript. Session A writes canonical `LUCIA_RELAY.json` plus a generated
56
+ human view; session B checks the Git fingerprint, reads the exact next action
57
+ and refuted hypotheses, re-runs verification, then explicitly consumes the
58
+ relay.
48
59
 
49
- | Moment | Skill | What it does |
50
- |---|---|---|
51
- | First time in a repository | `/luciazero-bootstrap` | Detects or creates the verify command, adds 3–6 smoke tests and a project notes file, proves the verify can actually go red |
52
- | A bug survives the first look | `/debug` | Deterministic reproduction, hypothesis ledger seeded from past lessons (`docs/lessons.md` + cross-repo heuristics), closes with a red-before-fix regression test |
53
- | About to say "done" | `/done` | Full-tier verify with the decisive line quoted, skeptic pass over the diff, `revert-probe.sh` test-honesty check, fixed report format |
54
- | Stopping while work is unfinished | `/handoff` | Writes the `HANDOFF.md` capsule: goal, verified state, the one literal next command |
55
- | "Make it faster" requests | `/experiment` | Metric and win threshold before any edit, baseline with repetitions, one variable per run, losers reverted |
56
- | After a hard task or a long debug | `/retro` | Routes lessons into the project's notes, the `docs/lessons.md` ledger, and cross-repo heuristics; reads the discipline stats log |
60
+ <p align="center">
61
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/relay-demo.gif" width="720" alt="One session creates a Lucia Relay; another validates it, detects repository drift, re-runs evidence, and consumes it">
62
+ </p>
57
63
 
58
- The `reviewer` agent is never invoked by name — `/done` spawns it when a diff is risky enough, or ask for "an adversarial review" at any point.
64
+ The GIF runs the [shipped implementation](docs/assets/relay-demo.sh) in a
65
+ temporary Git repository. CI's `relay-transfer` fixture scores the complete
66
+ reference 6/6 and rejects a generic Markdown handoff (1/6) plus a
67
+ content-complete but stale fingerprint (5/6). Those are mechanical protocol
68
+ checks—not model-uplift results. See the [method and limits](docs/benchmark.md#skill-protocol-evidence).
59
69
 
60
- ## What you get
70
+ ## Install
61
71
 
62
- No dependencies, no runtime (python3 only for the opt-in enforcement pack):
72
+ ### Claude Code plugin recommended
63
73
 
64
- | Piece | Scope | Loaded |
65
- |---|---|---|
66
- | `claude/luciazero.md` | Doctrine — 9 rules | Always, every project, every session |
67
- | `skills/luciazero-bootstrap/` | Procedure — make a repo agent-ready (ships `scripts/detect.sh`) | On demand |
68
- | `skills/debug/` | Procedure — hypothesis-driven debugging | On demand |
69
- | `skills/done/` | Procedure — closeout ritual (ships `scripts/revert-probe.sh`) | On demand |
70
- | `skills/handoff/` | Procedure — state capsule for the next session/agent | On demand |
71
- | `skills/experiment/` | Procedure — measured-change protocol for perf work | On demand |
72
- | `skills/retro/` | Procedure — harvest lessons into project notes | On demand |
73
- | `claude/agents/reviewer.md` | Adversarial reviewer subagent | On demand (before "done") |
74
- | `claude/hooks/` | Enforcement pack — verify-nudge hooks, opt-in strict gate, statusline | Opt-in |
75
- | `eval/` | A/B harness — 4 planted-bug tasks, self-proving graders | Manual (costs API money) |
76
- | `demo.sh` | Two-minute demo — planted bug, your session, objective grader | Manual |
74
+ Carries the doctrine, all skills, reviewer, and verify-tracking hooks:
77
75
 
78
- How it stacks up against superpowers, SuperClaude, proof-loop, and the harness built-ins — including what they do better: [docs/comparison.md](docs/comparison.md).
76
+ ```text
77
+ /plugin marketplace add ohm41321/luciazero
78
+ /plugin install luciazero@luciazero
79
+ ```
79
80
 
80
- ## What it looks like
81
+ Start a repository with `/luciazero:luciazero-bootstrap`. Plugin skills use the
82
+ `/luciazero:` prefix. The plugin has no statusline because Claude Code plugins
83
+ cannot set one.
81
84
 
82
- Actual output of the shipped scripts, not mockups. The statusline keeps the verify state on screen:
85
+ ### Skills only any compatible agent
83
86
 
84
- ```
85
- Opus | unverified # edits made, no verify run since
86
- Opus | ✅ verify 3m # last verify green, 3 minutes ago
87
- Opus | ❌ verify RED 40s # last verify failed — the loop is not done
87
+ ```bash
88
+ npx skills add ohm41321/luciazero
88
89
  ```
89
90
 
90
- Ending a session with unverified edits triggers the one-shot nudge:
91
-
92
- ```
93
- Doctrine rule 1: edits were made but no verify command has run since the last
94
- edit. Run the repo's verify command and quote its decisive line — or finish
95
- anyway and say plainly that the change is unverified. (This nudge fires once.)
96
- ```
91
+ This installs the 9 skills only: no doctrine, reviewer, or hooks.
97
92
 
98
- And in opt-in strict mode, a red verify actually blocks the stop, evidence attached:
93
+ ### Classic Claude Code and Codex
99
94
 
100
- ```
101
- Strict verify gate: './test.sh' is RED. Fix it before finishing — or say
102
- plainly that you are handing back a red state. Failing output:
95
+ ```bash
96
+ npx luciazero # Claude Code
97
+ npx luciazero --with-hooks # Claude Code + hooks/statusline; needs Python 3
98
+ npx luciazero codex # Codex CLI
103
99
 
104
- test_totals ... FAIL: expected 14, got 8
100
+ npx luciazero uninstall
101
+ npx luciazero uninstall-codex
105
102
  ```
106
103
 
107
- ## Classic install & enforcement pack
104
+ Pick either plugin or classic for Claude Code so hooks are not wired twice.
105
+ Classic installs support `--status`; Codex receives the doctrine and skills but
106
+ not Claude-only hooks/statusline. Installers back up name collisions and remove
107
+ only exact Luciazero-managed copies on uninstall.
108
108
 
109
- `./install.sh` does four things: copies `claude/luciazero.md` → `~/.claude/luciazero.md`, the six skills → `~/.claude/skills/`, the reviewer agent → `~/.claude/agents/reviewer.md` (backing up a customized copy first), and appends `@luciazero.md` to `~/.claude/CLAUDE.md`. It backs up `CLAUDE.md` before touching it, is idempotent, and never writes outside `~/.claude/`. Those four steps are also the whole manual install.
109
+ ## Update
110
110
 
111
- ### Enforcement pack (opt-in)
111
+ Luciazero never changes classic or Codex files in the background.
112
112
 
113
113
  ```bash
114
- ./install.sh --with-hooks # requires python3
114
+ npx luciazero@latest check-update # read-only; contacts npm only now
115
+ npx luciazero@latest update # updates every detected classic/Codex install
115
116
  ```
116
117
 
117
- Wires two scripts into `~/.claude/settings.json` (backed up; merge is additive and idempotent): a **verify-nudge Stop hook** — if edits were made but no verify-ish command ran since the last edit, ending the session triggers the one-shot nudge above; fires once, never loops, fails open — and the **statusline** (left untouched if you have a custom one). The stop hook also appends one line per stop outcome (`stop-clean` / `nudge` / `strict-block`) to `luciazero-stats.log` in the config dir local only, capped at ~250 lines, fail-open — which `/retro` reads to turn recurring discipline gaps into recorded lessons.
118
-
119
- What counts as a verify run is a broad regex (test.sh, pytest, `npm test`, `cargo test`, …) — override with `LUCIAZERO_VERIFY_REGEX`, or better, set the repo's exact command with `LUCIAZERO_VERIFY_CMD` (e.g. in the repo's `.claude/settings.local.json` `env` block): in exact mode only commands that *are* or *start with* it count, so `cat test.sh` cannot flip the state green. Documentation writes (`*.md` and friends — `LUCIAZERO_DOC_REGEX`) do not re-arm the nudge, because the closeout skills all write notes *after* the final green verify. A `SessionStart` hook prints a one-line pointer when the project has a `HANDOFF.md` capsule (staleness warning past `LUCIAZERO_HANDOFF_STALE_DAYS`, default 7) — the pointer only, never the contents.
120
-
121
- **Strict mode (opt-in on top of opt-in).** Set `LUCIAZERO_STRICT_VERIFY_CMD` to your repo's *fast* verify command — in your **personal** settings, never in anything committed. Honest limitation: the hook reads an environment variable and cannot tell which settings scope set it — a repo's committed `.claude/settings.json` `env` block would reach it too — so treat a repository that ships this variable as hostile and remove it before working there. At session stop the hook actually runs the command (unless the tracked state is already green after the last edit) and **blocks the stop** on red, quoting the failing output. Hard timeout via `LUCIAZERO_STRICT_TIMEOUT` (default 120s); every internal error — timeout, missing command, broken JSON — degrades to the ordinary nudge, never a block. A blocked stop's continuation is never re-blocked (`stop_hook_active`): a speed bump with evidence attached, not a wall.
122
-
123
- ### Verify, update, uninstall
124
-
125
- `./install.sh --status` is a read-only health check: doctrine, skills, agent, import line, version, and — with the enforcement pack — that hook files are executable *and actually wired* (hooks fail open, so a broken install is otherwise silent). Non-zero exit if a core piece is missing. Update with `git pull && ./install.sh` (idempotent; a version sidecar lets `--status` flag an install older than the checkout). `./uninstall.sh` removes the scripts and cleans exactly our settings entries, matched by full path — run it from a checkout at least as new as the one you installed from.
126
-
127
- ### Codex CLI
128
-
129
- `./install-codex.sh` (remove with `./uninstall-codex.sh`) — same content, single source of truth, converted at install time:
130
-
131
- | Piece | Lands in Codex as |
132
- |---|---|
133
- | Doctrine | Marker-delimited block in `~/.codex/AGENTS.md` (replaced in place on reinstall) |
134
- | All six skills | `~/.codex/skills/` — same `SKILL.md` format, copied as-is |
135
- | `reviewer` agent | `~/.codex/skills/reviewer/` — Codex has no subagents, so it ships as a skill |
136
- | Enforcement pack | Not installed — Codex has no hooks or statusline |
137
-
138
- Honors `CODEX_HOME`, backs up `AGENTS.md`, idempotent, writes nothing outside the Codex dir. The doctrine and skills are written platform-neutrally, so the same text works in both CLIs without translation.
139
-
140
- ## What the doctrine says
141
-
142
- Nine rules in four groups. Full text in `claude/luciazero.md`.
143
-
144
- **Ground truth** — done is proven by an exit code, and a run that did not happen is reported as exactly that; a missing verify command is the first bug; never weaken a check to reach green.
118
+ `update` preserves whether the Claude classic install uses hooks, repairs stale
119
+ managed files, starts no fresh install when it cannot find one, and stops on a
120
+ known newer version or malformed version metadata. Start a new agent session
121
+ afterward.
145
122
 
146
- **Loop** debugging starts with a hypothesis and the command that would refute it, not an edit, and the reproduction becomes a regression test; orient in an unfamiliar repo before editing — CI is the honest source of truth; smallest reversible step; review the final diff as a skeptic — risky diffs get an independent adversarial review.
123
+ Other install channels use their own updater:
147
124
 
148
- **Memory** — never re-derive a dead end twice: write down what the code cannot say (null results, footguns) and read the project's notes before working in an area they cover.
125
+ ```bash
126
+ claude plugin update luciazero@luciazero # then run /reload-plugins
127
+ npx skills update # review the scope prompt
128
+ ```
149
129
 
150
- **Autonomy** stop and ask a clear, decidable question before high-stakes or irreversible moves (delete data, deploy, production, public contracts, money, scope changes); everything else proceeds, with unknowns batched into one sharp question; finish the whole scope, naming anything left out.
130
+ The skills command updates every installed skill in the selected scope, not
131
+ only Luciazero; review its prompt before confirming.
151
132
 
152
- It is deliberately short, and `test.sh` enforces a word-count ceiling on it, because every line costs context on every turn of every session. Rules that merely restated what 2026 harnesses already enforce by default were removed; the CHANGELOG records each removal and the default it relies on.
133
+ Claude Code can auto-update the plugin at startup: open `/plugin`
134
+ **Marketplaces** → **luciazero** → **Enable auto-update**. Third-party
135
+ marketplaces leave this off by default. For release-only notifications, use
136
+ GitHub **Watch → Custom → Releases**.
153
137
 
154
- ## What the skills do
138
+ ## The 9 skills
155
139
 
156
- `/luciazero-bootstrap` walks a repository through six phases: **detect** (run the bundled `scripts/detect.sh` evidence scan, then read the CI config — CI is the source of truth; the script surfaces candidates, the agent decides), **establish the verify command** (use the existing one or create the smallest real one: non-zero on failure, unattended, offline, *timed once* — the measurement decides one tier or two; monorepos scope the fast tier), **smoke tests** (3–6 that catch catastrophic breakage — not coverage, and it says so), **guardrails** (only hooks that pay for themselves; on Codex, encoded as `AGENTS.md` instructions), **project notes** (only what reading the code cannot tell you), and **prove it** (run the fast tier twice — a green that does not repeat is a flake; break a covered line, confirm red, restore). Language-agnostic throughout: it detects, it does not assume.
140
+ Run `/luciazero-bootstrap` first; the rest activate when their moment arrives.
157
141
 
158
- `/debug` expands the hypothesis rule for bugs that resist the first look: reproduce deterministically, minimize, keep a visible hypothesis ledger (each entry names the command that would refute it), one variable per iteration, revert failed fixes, close with a regression test that is red before the fix and green after. The ledger seeds itself from recorded experience first — the repo's `docs/lessons.md` and the cross-repo `luciazero-heuristics.md` are grepped for the symptom before new hypotheses are invented; a match starts as H1, still verified.
142
+ | Moment | Skill | Result |
143
+ |---|---|---|
144
+ | Entering a repository | `/luciazero-bootstrap` | Finds or creates a verify command and proves it can fail |
145
+ | Before risky or multi-step work | `/plan` | Fixes scope and observable acceptance evidence |
146
+ | A bug survives the first look | `/debug` | Reproduction, hypothesis ledger, regression test |
147
+ | Good and bad revisions are known | `/bisect` | Finds the first bad commit in a temporary worktree |
148
+ | Before claiming completion | `/done` | Full verify, skeptic review, scope report |
149
+ | Work must move elsewhere | `/lucia-relay` | Portable JSON + Markdown state with drift inspection |
150
+ | Optimizing performance | `/experiment` | Baseline, threshold, controlled measurement |
151
+ | Reviewing local verify habits | `/discipline-report` | Time/project-filtered local outcome report |
152
+ | After difficult work | `/retro` | Stores reusable lessons and disproved approaches |
159
153
 
160
- `/done` is the closeout ritual: full-tier verify with the decisive line quoted, a skeptic pass over the final diff, an independent adversarial review when the diff earns it, an explicit scope check naming anything left out, and a fixed report format. The test-honesty question — *would the new tests fail if the change were reverted?* — has a mechanical form: the bundled `scripts/revert-probe.sh` checks the old code into a throwaway git worktree, overlays only the changed test files, runs your verify command there, and inverts the result (exit 0/1/2 = bites/vacuous/unassessable).
154
+ Risky diffs also pass through one read-only `reviewer` with `security`,
155
+ `contract`, or `general` focus. Security and contract risk together receive two
156
+ separate passes.
161
157
 
162
- `/handoff` writes a state capsule (`HANDOFF.md`) when a session ends mid-task: goal, verified state, the one literal next command, open and refuted hypotheses, landmines. The next session — or the other harness — reads it, re-verifies against the tree, and deletes it.
158
+ ## Evidence
163
159
 
164
- `/experiment` is the measured-change protocol for "make it faster" work: metric and win threshold defined before touching code, baseline with repetitions, one variable per experiment, verdict recorded to `docs/experiments.md` — where a null result is worth as much as a win, and losers are reverted immediately.
160
+ <!-- BEGIN GENERATED: benchmark-evidence -->
165
161
 
166
- `/retro` closes the loop on *never re-derive a dead end twice*: after a hard task it filters the session for what **reading the code cannot tell a future agent** (null results, footguns, environment quirks), routes repo-true lessons into the project's notes and machine-local facts into the harness's memory (never committed), updates instead of duplicating, and deletes notes the session disproved. Three learning stores make this compound over time: debugged failures land in the repo's `docs/lessons.md` in a fixed greppable shape (symptom → cause → proven-by → fix) that `/debug` reads next time; lessons true in every repository go to `luciazero-heuristics.md` in the config dir (one line each, hard 100-line cap — an unbounded heuristics file would become the context tax this pack exists to prevent); and the enforcement pack's stats log turns recurring nudges into recorded behavioral lessons. Uninstall keeps all three — they are learned data. An empty retro is a valid retro — and knowledge stops evaporating when the session ends.
162
+ ### Claude results
167
163
 
168
- ## The adversarial check: `reviewer` agent
164
+ Snapshot: 2026-08-11. All-criteria pass rate generated from checked-in raw rows:
169
165
 
170
- An exit code cannot catch *passes-the-tests-but-wrong*. For risky diffs the doctrine wants an independent adversarial review: on Claude Code the built-in `/code-review` is the stronger tool when available; the shipped `reviewer` agent is the portable fallback and the only reviewer on Codex. Read-only, instructed to **refute** the change, runs on the same model as the main thread (`model: inherit`), and reports `No findings.` rather than inventing some.
166
+ | Claude model | Luciazero | Bare | Difference |
167
+ |---|---:|---:|---:|
168
+ | Haiku†, 10 valid/task | 36/60 (60%) | 27/60 (45%) | +15pp |
169
+ | Sonnet, 4–5 valid/task* | 25/27 (93%) | 16/26 (62%) | +31pp |
171
170
 
172
- ## Design notes
171
+ The `Luciazero` arm installs the classic pack without hooks; it is not a clean
172
+ doctrine-only ablation. *Sonnet is preliminary because eight invalid rows leave
173
+ several arms at four valid runs. The previously stated `+37pp` top-up is retired
174
+ because its replacement raw rows could not be recovered.
173
175
 
174
- **Why a file, not a hook.** Hooks enforce mechanical, deterministic things; doctrine is judgment, and judgment belongs in context. Claude Code already re-injects `CLAUDE.md` after compaction — the real anti-drift lever is keeping the doctrine small, which `test.sh` enforces.
176
+ †Model provenance is incomplete for Haiku: only 70/140 rows encode model
177
+ identity. The other 70 are attributed at campaign-file/report level and
178
+ cannot be independently verified per row.
175
179
 
176
- **Why the doctrine and the skills are separate.** The doctrine must be cheap enough to carry on every turn; the procedures are long and moment-specific, so they load on demand. Merging them would make you pay for the procedures constantly.
180
+ ### GPT/Codex pilot exploratory
177
181
 
178
- **How the plugin squares with this.** Plugins have no way to import a file into `CLAUDE.md`, so the plugin channel delivers the doctrine as `SessionStart` context — acceptable only because the text is word-ceiling-capped, and guarded so it stays silent when a classic install already imports it. The classic installer remains the reference channel; the plugin trades the statusline and `--status` for one-command install and marketplace updates.
182
+ Snapshot: 2026-08-12.
179
183
 
180
- **Project settings stay in the project.** `examples/project-settings.example.json` shows the per-repo shape a permission allowlist so the verify loop is not interrupted, and an inert check-suppression guard that mechanizes "never weaken a check to reach green". Copy into a repo's `.claude/settings.json`; do not put project commands in global settings.
184
+ | Model | Valid invocations | Paired tasks | Luciazero | Bare | Observed difference |
185
+ |---|---:|---:|---:|---:|---:|
186
+ | GPT-5.6 Terra, medium | 11/12* | 5 | 5/5 runs, 28/28 criteria | 5/5 runs, 28/28 criteria | +0pp† |
181
187
 
182
- **Agentic CI stays a diagnosis loop.** `examples/luciazero-ci.example.yml` (inert, REPLACE-ME-gated) posts an agent's root-cause diagnosis on a PR when CI fails. It cannot push or edit code (`contents: read`, no Bash in the allowlist, no credentials); its one write scope posts the size-capped diagnosis comment. It never auto-fixes: an agent patching CI blind ships plausible-but-wrong fixes.
188
+ *One Luciazero run was invalidated by model capacity. †This is a
189
+ **ceiling-effect warning, not evidence of uplift or no effect**: the pilot has
190
+ only one run per arm per task. See the [full benchmark](docs/benchmark.md),
191
+ [campaign registry](eval/results/campaigns.json), and
192
+ [raw pilot rows](eval/results/gpt-5.6-terra-medium-pilot-2026-08-12.jsonl).
183
193
 
184
- <p align="center">
185
- <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia-laptop.png" width="240" alt="Lucia grinding through the eval harness on her laptop">
186
- </p>
194
+ <!-- END GENERATED: benchmark-evidence -->
187
195
 
188
- **The setup measures itself.** `eval/` is a small A/B harness: the same planted-bug tasks run with and without the doctrine installed, graded offline by behavioral criteria. Four tasks, each probing a different rule — slugify (regression-test discipline), red-suite (bending tests toward a bug), flaky-report (making an intermittent failure deterministic), pipeline (root-cause vs symptom patch, graded by diff locality). CI proves every grader three ways on every push: `reference/` passes, unfixed `project/` fails, and the checked-in `gamed/` cheat trees are rejected. `eval/run.sh --runs N` + `eval/report.sh` produce per-criterion pass-rate tables; see `eval/README.md`, including its honesty box about small n.
196
+ ## Requirements and safety
189
197
 
190
- ## Safety
198
+ - Node.js 18+ for the CLI and discipline report.
199
+ - Bash for classic installers; Python 3 for hooks and Lucia Relay.
200
+ - Core installers, hooks, helpers, and graders are offline. Real behavioral
201
+ evals invoke a model CLI and consume API credit or subscription quota.
202
+ - Hooks run commands on your machine. Read them before enabling them.
203
+ - Set `LUCIAZERO_VERIFY_CMD` to the repo's exact fast verify command.
204
+ - Put `LUCIAZERO_STRICT_VERIFY_CMD` only in personal settings, never in a
205
+ committed repository config. Strict mode fails open on internal errors.
191
206
 
192
- Hooks execute commands on your machine automatically. The example settings file is inert by design — every hook in it is commented out and must be edited before it does anything. Read any hook before enabling it, and do not enable one that pushes, deploys, deletes, or writes outside the repository.
207
+ See [SECURITY.md](SECURITY.md) for the complete trust boundary.
193
208
 
194
209
  ## Development
195
210
 
196
- `./test.sh` is this repo's own verify command — the doctrine says a missing verify command is the first bug, so the repo passes its own rule. It covers shell syntax + shellcheck, the hook state machine (strict gate included), plugin + npm manifests, every eval grader proven red *and* green *and* anti-cheat, `revert-probe.sh` in throwaway git fixtures, `demo.sh`, and full install → reinstall → uninstall cycles for both harnesses in sandbox config dirs — never your real `~/.claude/` or `~/.codex/`. CI runs it on every push; tagging `vX.Y.Z` publishes a GitHub Release. See `CONTRIBUTING.md` and [docs/publishing.md](docs/publishing.md).
197
-
198
- ```
199
- $ ./test.sh
200
- PASS all checks green
211
+ ```bash
212
+ ./test.sh
201
213
  ```
202
214
 
203
- <p align="center">
204
- <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia-cheer.png" width="240" alt="Lucia celebrating all checks green">
205
- </p>
215
+ The suite covers scripts, hook state, Relay, bisect, plugin/npm manifests,
216
+ self-proving eval graders, and sandboxed install reinstall → uninstall for
217
+ Claude Code and Codex.
206
218
 
207
- ## Lucia family & support
219
+ More detail:
220
+
221
+ - [Architecture and trade-offs](docs/comparison.md)
222
+ - [Eval methodology](eval/README.md)
223
+ - [Benchmark results and GPT plan](docs/benchmark.md)
224
+ - [Raw campaign registry](eval/results/campaigns.json)
225
+ - [Experiment log](docs/experiments.md)
226
+ - [Contributing](CONTRIBUTING.md)
227
+ - [Publishing](docs/publishing.md)
228
+ - [Changelog](CHANGELOG.md)
208
229
 
209
- Luciazero shares its mascot with [Lucia](https://lucia-discord-bot.vercel.app) a Thai-language Discord bot with AI chat, music playback, mini-games, and a gacha card collection.
230
+ ## Lucia family & support
210
231
 
211
- If Luciazero saves you review cycles, you can [support the project here](https://easydonate.app/itsathitz) 💚
232
+ Luciazero shares its mascot with [Lucia](https://lucia-discord-bot.vercel.app),
233
+ a Thai-language Discord bot. If Luciazero saves you review cycles, you can
234
+ [support the project here](https://easydonate.app/itsathitz) 💚
212
235
 
213
236
  ## License
214
237