luciazero 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,18 +7,165 @@ 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.0] - 2026-08-13
11
11
 
12
12
  ### Changed
13
13
 
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.
14
+ - The canonical Sonnet result is explicitly preliminary (`+31pp`, n=4–5).
15
+ The historical `+37pp` statement is retired because its eight replacement
16
+ raw rows could not be recovered.
17
+ - `eval/report.sh` rejects mixed campaigns/commits/seeds, changed fixture
18
+ hashes, duplicate invocation IDs, and inconsistent pair order. Published
19
+ evidence also enforces registered task/arm/row/invalid/model expectations,
20
+ and discloses Haiku's incomplete per-row model provenance.
21
+ - Eval tasks may provide deterministic offline setup before either arm. Provider
22
+ transcripts now live outside worked trees so they cannot alter Git status,
23
+ repository fingerprints, or final-tree grading.
24
+ - Relay fingerprints encode untracked special files without opening them, so a
25
+ FIFO, socket, or device cannot block inspection or trigger device I/O.
26
+ - GitHub workflows use the Node 24-based `actions/checkout@v5` and
27
+ `actions/setup-node@v5` runtimes.
28
+ - **Breaking: `/handoff` is now `/lucia-relay`.** The branded name avoids
29
+ collisions with generic handoff skills. Installs remove an untouched v1.5
30
+ copy but preserve and warn about customized copies. Relay state is now a
31
+ validated `LUCIA_RELAY.json` manifest plus a generated human view, with a
32
+ repository fingerprint, verification evidence, negative knowledge,
33
+ cross-session/cross-agent routing, drift inspection, and explicit consume.
34
+ - **Risk-routed review.** The single portable reviewer now accepts `general`,
35
+ `security`, and `contract` focus modes, reads callers/consumers, and uses one
36
+ blocker/major/minor policy. `/done` requests separate focused passes when a
37
+ diff crosses both security and contract boundaries.
38
+ - **Smart verification is repo-owned.** Monorepos create `verify-changed` from
39
+ their native task graph and keep `verify-full` for closeout. The global hook
40
+ never guesses dependency impact from path prefixes.
41
+ - **Classic and Codex installs track component ownership.** Exact hidden
42
+ snapshots distinguish Luciazero-managed skills/agents from same-name user or
43
+ third-party components. Updates back up collisions/customizations, and
44
+ uninstall removes only an unchanged managed copy.
45
+
46
+ ### Added
47
+
48
+ - Auditable benchmark evidence: canonical Claude raw JSONL, a SHA-256 campaign
49
+ registry, generated README/benchmark tables, and a CI drift check.
50
+ - Result schema 2 records campaign, pair, invocation, repository, fixture,
51
+ prompt, platform, and arm-order metadata. Seeded arm randomization reduces
52
+ fixed-order bias without making campaigns irreproducible.
53
+ - Strict shared result validation rejects unsupported schemas and mistyped
54
+ booleans, criteria, metrics, timestamps, platform, and campaign metadata.
55
+ Output-aware `--resume` fills interrupted pairs without rerunning completed
56
+ invocation IDs; `--run-offset` extends completed batches.
57
+ - Three zero-quota candidate eval tasks cover archive extraction security,
58
+ lossless atomic schema migration, and multi-page cursor integration. Each
59
+ grader proves reference/project/anti-gamed behavior offline.
60
+ - **`relay-transfer` protocol eval** grades portable state, an exact next edit,
61
+ verification evidence, negative knowledge, scope preservation, and a current
62
+ repository fingerprint. CI proves its 6/6 reference and rejects generic
63
+ prose plus a content-complete stale relay without spending model quota.
64
+ - **Lucia Relay demo** drives the shipped producer/receiver implementation in
65
+ a temporary Git repository: render, validate, detect drift, re-run evidence,
66
+ and explicitly consume. The checked-in GIF is generated from the same script
67
+ exercised by CI.
68
+ - **Central component catalogs** drive classic/Codex install, status,
69
+ uninstall, and inventory tests, so a new skill or agent cannot silently ship
70
+ through only one channel.
71
+ - **`/plan`** defines falsifiable acceptance signals and reversible steps,
72
+ while pausing for approval only on ambiguity, high stakes, destructive work,
73
+ public-contract choices, or scope changes.
74
+ - **`/bisect` + `safe-bisect.sh`** locate the first bad commit in a detached
75
+ temporary worktree, repeat endpoints to catch flakes, preserve exit 125
76
+ skips, distinguish missing commands, and clean every exit path.
77
+ - **`npx luciazero discipline` + `/discipline-report`** analyze schema-v2
78
+ local JSONL outcomes with day/project filters and JSON output. The hook logs
79
+ a privacy-preserving project hash and verify mode; legacy records remain
80
+ readable and recommendations distinguish observations from likely causes.
81
+ - **`/lucia-relay` carries memory pointers** — the `Read first`
82
+ section quotes the `docs/lessons.md` entries relevant to the unfinished
83
+ work (a selection, never a copy — the ledger travels with the repo) and
84
+ copies applicable machine-local `luciazero-heuristics.md` entries
85
+ verbatim, since the relay is the only way those cross machines. The
86
+ consume protocol tells the reader to follow the pointers before touching
87
+ code and to adopt carried heuristics that earn their keep.
88
+
89
+ - **`eval/run.sh --use-login`** — run the real eval on an existing Claude
90
+ subscription (Pro/Max) instead of API dollars: seeds each per-run sandbox
91
+ config dir with this machine's login state — `~/.claude.json`, plus
92
+ OAuth tokens from `.credentials.json` (Linux) or a Keychain export
93
+ (macOS). The copy lives only inside the mktemp sandbox and is deleted
94
+ with it. Fail-soft by
95
+ design: if the seed does not authenticate, `check-result.sh` marks the
96
+ arm INVALID and nothing is spent. Plumbing (seed per arm, warn on missing
97
+ login state) is proven offline in `test.sh`.
98
+
99
+ - **`eval/check-result.sh`** — a zero exit code no longer proves the agent
100
+ ran: the CLI has wrapped a `Not logged in` error in subtype `"success"`
101
+ (observed 2026-08-11, caught free by a 1-run smoke). The guard inspects
102
+ the result payload (`is_error`, `terminal_reason: api_error`, login
103
+ errors) and `run.sh` books a refuted arm as INVALID with the reason
104
+ quoted; every accept/reject path is fixture-proven in `test.sh`.
105
+ - **`eval/run.sh --offline`** — synthetic smoke mode: no `claude` CLI, no
106
+ API key, zero cost. Doctrine-style arms get the task's `reference/` tree,
107
+ bare keeps the planted bug, and the whole copy → grade → JSONL → report
108
+ loop runs in seconds. Rows are branded `"offline": true` and `report.sh`
109
+ prints a SYNTHETIC banner so the numbers can never pass as behavioral
110
+ results; end-to-end proven in `test.sh` plus a frozen fixture pair.
111
+ - **README narrative reorder** (EN + TH): the demo GIF and the
112
+ "What it prevents" table now sit directly under the intro, before
113
+ Install — a newcomer sees what the pack does in 30 seconds before being
114
+ asked to install anything.
115
+
116
+ - **README demo GIF** — 15 seconds of the enforcement pack's real behavior:
117
+ edit → `✎ unverified`, stop attempt → the rule-1 nudge, red verify →
118
+ `❌ verify RED`, fix → `✅ verify`. Recorded from the checked-in
119
+ `docs/assets/statusline-demo.sh`, which drives the shipped hooks in a
120
+ sandbox (so the GIF cannot drift from what the scripts actually print),
121
+ via the checked-in `docs/assets/demo.tape` (`vhs`). The driver script is
122
+ under `test.sh`'s shellcheck net.
123
+
124
+ - **`false-green` eval task** (sixth): the false-done trap — the shipped
125
+ suite is green from the start while the CSV escaping bug lives outside
126
+ its coverage. The untouched tree *passes its own tests* and still fails
127
+ the grader (symptom probed on unseen data; bug-restored suite must go
128
+ red), which is doctrine rule 1 stated as a fixture. `gamed/` (comma-only
129
+ half fix) and `gamed-notest/` (correct fix, no test added) are rejected.
130
+ - **`--with-lessons` eval arm** — `eval/run.sh --with-lessons` runs a third
131
+ arm for tasks that ship a `lessons.md` (currently `pipeline` and
132
+ `false-green`): doctrine install plus the task's ledger pre-seeded as
133
+ `docs/lessons.md`, the A/B/C comparison that measures whether the
134
+ learning layer pays. `report.sh` discovers arm columns from the data and
135
+ renders per-arm deltas; frozen three-arm fixture added to `test.sh`.
136
+ - **Per-run resource accounting** — `run.sh --out` now records duration,
137
+ token usage, and cost per run (parsed fail-open from the CLI's
138
+ `--output-format json` result), and `report.sh` appends per-arm resource
139
+ means whenever the data is present — a pass-rate delta is only a win if
140
+ the cost next to it says so.
141
+ - **Community eval issue templates** — `Evaluation result` (report.sh
142
+ output required, null results explicitly welcome) and `New eval task`
143
+ (asks for the doctrine rule probed and the gamed tree that would cheat
144
+ the grader).
145
+
146
+ - **`merge-conflict` eval task** (fifth): an unresolved merge where main's
147
+ bulk discount and the branch's member discount must both survive. The
148
+ grader probes each feature on data the shipped tests never mention, and
149
+ swaps in one-sided feature mutants to prove the worked tests actually
150
+ cover both sides — `gamed/` (HEAD-only resolution, suite green) and
151
+ `gamed-notests/` (correct merge, no tests added) are both rejected.
152
+ - **Machine-readable closeout evidence** — `/done` step 6 now mirrors the
153
+ report as a JSON block (status, verify command + exit code + decisive
154
+ line, not-covered, left-out) when the result feeds CI, a PR comment, or a
155
+ dashboard.
156
+ - **README "What it prevents" section** (EN + TH): failure modes mapped to
157
+ the shipped mechanism that catches each — no promise without a mechanism.
158
+ - **SECURITY.md** — private reporting channel plus the enforced design
159
+ guarantees (no network, no npm lifecycle scripts, fail-open hooks,
160
+ config-dir-only writes) and the documented strict-mode env sharp edge.
161
+ - **GitHub issue templates** — bug report (channel + decisive-output
162
+ evidence required), feature request (doctrine-fit question), security
163
+ contact link.
164
+
165
+ ## [1.5.0] - 2026-08-10
166
+
167
+ First version published to npm (`luciazero`); 1.4.x and below were
168
+ development versions.
22
169
 
23
170
  ### Added
24
171
 
package/README.md CHANGED
@@ -7,208 +7,202 @@
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
- ```
27
-
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`.
23
+ ## See it in 15 seconds
29
24
 
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:
25
+ This GIF is driven by the shipped hooks, not a mockup:
31
26
 
32
- ```
33
- npx skills add ohm41321/luciazero
34
- ```
35
-
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:
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>
37
30
 
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)
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
41
35
  ```
42
36
 
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.
44
-
45
- ## After installing: which skill when
37
+ ## What it prevents
46
38
 
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`, …)
48
-
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 |
57
-
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.
59
-
60
- ## What you get
61
-
62
- No dependencies, no runtime (python3 only for the opt-in enforcement pack):
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 |
63
48
 
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 |
49
+ Mechanical guarantees run in `test.sh`; behavioral claims are measured by the
50
+ [eval harness](eval/README.md).
77
51
 
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).
52
+ ## Carry unfinished work across agents
79
53
 
80
- ## What it looks like
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.
81
59
 
82
- Actual output of the shipped scripts, not mockups. The statusline keeps the verify state on screen:
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>
83
63
 
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
88
- ```
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).
89
69
 
90
- Ending a session with unverified edits triggers the one-shot nudge:
70
+ ## Install
91
71
 
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
- ```
72
+ ### Claude Code plugin — recommended
97
73
 
98
- And in opt-in strict mode, a red verify actually blocks the stop, evidence attached:
74
+ Carries the doctrine, all skills, reviewer, and verify-tracking hooks:
99
75
 
76
+ ```text
77
+ /plugin marketplace add ohm41321/luciazero
78
+ /plugin install luciazero@luciazero
100
79
  ```
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:
103
-
104
- test_totals ... FAIL: expected 14, got 8
105
- ```
106
-
107
- ## Classic install & enforcement pack
108
80
 
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.
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.
110
84
 
111
- ### Enforcement pack (opt-in)
85
+ ### Skills only — any compatible agent
112
86
 
113
87
  ```bash
114
- ./install.sh --with-hooks # requires python3
88
+ npx skills add ohm41321/luciazero
115
89
  ```
116
90
 
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
91
+ This installs the 9 skills only: no doctrine, reviewer, or hooks.
141
92
 
142
- Nine rules in four groups. Full text in `claude/luciazero.md`.
93
+ ### Classic Claude Code and Codex
143
94
 
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.
145
-
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.
147
-
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.
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
149
99
 
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.
100
+ npx luciazero uninstall
101
+ npx luciazero uninstall-codex
102
+ ```
151
103
 
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.
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.
153
108
 
154
- ## What the skills do
109
+ ## The 9 skills
155
110
 
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.
111
+ Run `/luciazero-bootstrap` first; the rest activate when their moment arrives.
157
112
 
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.
113
+ | Moment | Skill | Result |
114
+ |---|---|---|
115
+ | Entering a repository | `/luciazero-bootstrap` | Finds or creates a verify command and proves it can fail |
116
+ | Before risky or multi-step work | `/plan` | Fixes scope and observable acceptance evidence |
117
+ | A bug survives the first look | `/debug` | Reproduction, hypothesis ledger, regression test |
118
+ | Good and bad revisions are known | `/bisect` | Finds the first bad commit in a temporary worktree |
119
+ | Before claiming completion | `/done` | Full verify, skeptic review, scope report |
120
+ | Work must move elsewhere | `/lucia-relay` | Portable JSON + Markdown state with drift inspection |
121
+ | Optimizing performance | `/experiment` | Baseline, threshold, controlled measurement |
122
+ | Reviewing local verify habits | `/discipline-report` | Time/project-filtered local outcome report |
123
+ | After difficult work | `/retro` | Stores reusable lessons and disproved approaches |
159
124
 
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).
125
+ Risky diffs also pass through one read-only `reviewer` with `security`,
126
+ `contract`, or `general` focus. Security and contract risk together receive two
127
+ separate passes.
161
128
 
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.
129
+ ## Evidence
163
130
 
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.
131
+ <!-- BEGIN GENERATED: benchmark-evidence -->
165
132
 
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.
133
+ ### Claude results
167
134
 
168
- ## The adversarial check: `reviewer` agent
135
+ Snapshot: 2026-08-11. All-criteria pass rate generated from checked-in raw rows:
169
136
 
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.
137
+ | Claude model | Luciazero | Bare | Difference |
138
+ |---|---:|---:|---:|
139
+ | Haiku†, 10 valid/task | 36/60 (60%) | 27/60 (45%) | +15pp |
140
+ | Sonnet, 4–5 valid/task* | 25/27 (93%) | 16/26 (62%) | +31pp |
171
141
 
172
- ## Design notes
142
+ The `Luciazero` arm installs the classic pack without hooks; it is not a clean
143
+ doctrine-only ablation. *Sonnet is preliminary because eight invalid rows leave
144
+ several arms at four valid runs. The previously stated `+37pp` top-up is retired
145
+ because its replacement raw rows could not be recovered.
173
146
 
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.
147
+ †Model provenance is incomplete for Haiku: only 70/140 rows encode model
148
+ identity. The other 70 are attributed at campaign-file/report level and
149
+ cannot be independently verified per row.
175
150
 
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.
151
+ ### GPT/Codex pilot exploratory
177
152
 
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.
153
+ Snapshot: 2026-08-12.
179
154
 
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.
155
+ | Model | Valid invocations | Paired tasks | Luciazero | Bare | Observed difference |
156
+ |---|---:|---:|---:|---:|---:|
157
+ | GPT-5.6 Terra, medium | 11/12* | 5 | 5/5 runs, 28/28 criteria | 5/5 runs, 28/28 criteria | +0pp† |
181
158
 
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.
159
+ *One Luciazero run was invalidated by model capacity. †This is a
160
+ **ceiling-effect warning, not evidence of uplift or no effect**: the pilot has
161
+ only one run per arm per task. See the [full benchmark](docs/benchmark.md),
162
+ [campaign registry](eval/results/campaigns.json), and
163
+ [raw pilot rows](eval/results/gpt-5.6-terra-medium-pilot-2026-08-12.jsonl).
183
164
 
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>
165
+ <!-- END GENERATED: benchmark-evidence -->
187
166
 
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.
167
+ ## Requirements and safety
189
168
 
190
- ## Safety
169
+ - Node.js 18+ for the CLI and discipline report.
170
+ - Bash for classic installers; Python 3 for hooks and Lucia Relay.
171
+ - Core installers, hooks, helpers, and graders are offline. Real behavioral
172
+ evals invoke a model CLI and consume API credit or subscription quota.
173
+ - Hooks run commands on your machine. Read them before enabling them.
174
+ - Set `LUCIAZERO_VERIFY_CMD` to the repo's exact fast verify command.
175
+ - Put `LUCIAZERO_STRICT_VERIFY_CMD` only in personal settings, never in a
176
+ committed repository config. Strict mode fails open on internal errors.
191
177
 
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.
178
+ See [SECURITY.md](SECURITY.md) for the complete trust boundary.
193
179
 
194
180
  ## Development
195
181
 
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
182
+ ```bash
183
+ ./test.sh
201
184
  ```
202
185
 
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>
186
+ The suite covers scripts, hook state, Relay, bisect, plugin/npm manifests,
187
+ self-proving eval graders, and sandboxed install reinstall → uninstall for
188
+ Claude Code and Codex.
206
189
 
207
- ## Lucia family & support
190
+ More detail:
191
+
192
+ - [Architecture and trade-offs](docs/comparison.md)
193
+ - [Eval methodology](eval/README.md)
194
+ - [Benchmark results and GPT plan](docs/benchmark.md)
195
+ - [Raw campaign registry](eval/results/campaigns.json)
196
+ - [Experiment log](docs/experiments.md)
197
+ - [Contributing](CONTRIBUTING.md)
198
+ - [Publishing](docs/publishing.md)
199
+ - [Changelog](CHANGELOG.md)
208
200
 
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.
201
+ ## Lucia family & support
210
202
 
211
- If Luciazero saves you review cycles, you can [support the project here](https://easydonate.app/itsathitz) 💚
203
+ Luciazero shares its mascot with [Lucia](https://lucia-discord-bot.vercel.app),
204
+ a Thai-language Discord bot. If Luciazero saves you review cycles, you can
205
+ [support the project here](https://easydonate.app/itsathitz) 💚
212
206
 
213
207
  ## License
214
208