luciazero 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,219 @@
1
+ **English** | [ภาษาไทย](README.th.md)
2
+
3
+ # Luciazero for Claude Code & Codex CLI
4
+
5
+ [![npm](https://img.shields.io/npm/v/luciazero)](https://www.npmjs.com/package/luciazero)
6
+ [![CI](https://github.com/ohm41321/luciazero/actions/workflows/ci.yml/badge.svg)](https://github.com/ohm41321/luciazero/actions/workflows/ci.yml)
7
+ [![license](https://img.shields.io/github/license/ohm41321/luciazero)](LICENSE)
8
+
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">
11
+ </p>
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:
14
+
15
+ > Done is proven by a command, not by my judgment. If no verification command exists, that is the first bug.
16
+
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.
18
+
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`.
29
+
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:
31
+
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:
37
+
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
+ ```
42
+
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
46
+
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):
63
+
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 |
77
+
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).
79
+
80
+ ## What it looks like
81
+
82
+ Actual output of the shipped scripts, not mockups. The statusline keeps the verify state on screen:
83
+
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
+ ```
89
+
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
+ ```
97
+
98
+ And in opt-in strict mode, a red verify actually blocks the stop, evidence attached:
99
+
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:
103
+
104
+ test_totals ... FAIL: expected 14, got 8
105
+ ```
106
+
107
+ ## Classic install & enforcement pack
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.
110
+
111
+ ### Enforcement pack (opt-in)
112
+
113
+ ```bash
114
+ ./install.sh --with-hooks # requires python3
115
+ ```
116
+
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.
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.
149
+
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.
151
+
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.
153
+
154
+ ## What the skills do
155
+
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.
157
+
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.
159
+
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).
161
+
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.
163
+
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.
165
+
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.
167
+
168
+ ## The adversarial check: `reviewer` agent
169
+
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.
171
+
172
+ ## Design notes
173
+
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.
175
+
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.
177
+
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.
179
+
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.
181
+
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.
183
+
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>
187
+
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.
189
+
190
+ ## Safety
191
+
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.
193
+
194
+ ## Development
195
+
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
201
+ ```
202
+
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>
206
+
207
+ ## Lucia family & support
208
+
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.
210
+
211
+ If Luciazero saves you review cycles, you can [support the project here](https://easydonate.app/itsathitz) 💚
212
+
213
+ ## License
214
+
215
+ [MIT](LICENSE)
216
+
217
+ ## ภาษาไทย
218
+
219
+ README ฉบับภาษาไทยเต็ม: [README.th.md](README.th.md)
package/README.th.md ADDED
@@ -0,0 +1,215 @@
1
+ [English](README.md) | **ภาษาไทย**
2
+
3
+ # Luciazero สำหรับ Claude Code & Codex CLI
4
+
5
+ [![npm](https://img.shields.io/npm/v/luciazero)](https://www.npmjs.com/package/luciazero)
6
+ [![CI](https://github.com/ohm41321/luciazero/actions/workflows/ci.yml/badge.svg)](https://github.com/ohm41321/luciazero/actions/workflows/ci.yml)
7
+ [![license](https://img.shields.io/github/license/ohm41321/luciazero)](LICENSE)
8
+
9
+ <p align="center">
10
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia.png" width="300" alt="Lucia — มาสคอตของ Luciazero — กอดตุ๊กตาแมว">
11
+ </p>
12
+
13
+ Luciazero ทำให้ coding agent รันลูป `plan → change → verify → fix` ของตัวเองจนจบ แทนที่จะส่งงานที่ยังไม่ได้พิสูจน์กลับมาให้เรา กฎข้อแรกของมันไม่ใช่เรื่อง prompt:
14
+
15
+ > เสร็จ ต้องพิสูจน์ด้วยคำสั่ง ไม่ใช่ด้วยความเห็นของฉัน ถ้าไม่มีคำสั่ง verify — นั่นคือบั๊กแรกที่ต้องแก้
16
+
17
+ ทุกอย่างใน repo นี้ — doctrine 9 ข้อ, skill หกตัว, reviewer agent สายหักล้าง, enforcement hooks, eval harness — มีไว้เพื่อทำให้กฎข้อนี้เป็นจริงโดยไม่ต้องมีคนคอยดูทุกลูป
18
+
19
+ ## ติดตั้ง
20
+
21
+ **Claude Code — plugin (แนะนำ)** ติดตั้งครั้งเดียวได้ครบ: skill ทั้งหก, agent `reviewer`, hook ติดตามการ verify และ doctrine:
22
+
23
+ ```
24
+ /plugin marketplace add ohm41321/luciazero
25
+ /plugin install luciazero@luciazero
26
+ ```
27
+
28
+ จากนั้นรัน `/luciazero:luciazero-bootstrap` ใน repository ไหนก็ได้ (skill ของ plugin ใช้ namespace: `/luciazero:done`, `/luciazero:debug`, …) บอกกันตรง ๆ: การติดตั้ง plugin คือสิ่งที่เปิดใช้ hook ของมัน — ขั้นตอนติดตั้งนั้นแหละ*คือ*การ opt-in; doctrine โหลดผ่าน hook `SessionStart` เพราะ plugin เติมบรรทัด import ลง `CLAUDE.md` ไม่ได้ (ข้อความชุดเดียวกันที่ถูกคุมเพดานจำนวนคำ และจะเงียบเมื่อมีการติดตั้งแบบ classic อยู่ จึงไม่มีทางโหลดซ้ำสองรอบ) และไม่มี statusline เพราะ Claude Code ไม่ให้ plugin ตั้ง `statusLine`
29
+
30
+ **Agent ตัวไหนก็ได้ — เอาเฉพาะ skill** ผ่าน [vercel-labs/skills](https://github.com/vercel-labs/skills) ลง Claude Code, Codex, Cursor และอีก 70+ ตัว ไม่มี doctrine ไม่มี reviewer agent ไม่มี hook:
31
+
32
+ ```
33
+ npx skills add ohm41321/luciazero
34
+ ```
35
+
36
+ **ติดตั้งแบบ classic** ช่องทางอ้างอิง — ช่องทางเดียวที่มี statusline, การ import เข้า `CLAUDE.md`, health check `--status` และตัวติดตั้งฝั่ง Codex CLI รายละเอียดอยู่ใน section ถัด ๆ ไป:
37
+
38
+ ```bash
39
+ npx luciazero # Claude Code (--with-hooks สำหรับ enforcement pack, --status)
40
+ npx luciazero codex # Codex CLI (ถอนด้วย npx luciazero uninstall)
41
+ ```
42
+
43
+ `npx luciazero` เป็น wrapper บาง ๆ ที่ไม่มี lifecycle script — ไม่มีอะไรรันตอน npm install (`test.sh` บังคับข้อนี้ไว้) มันแค่เรียก bash installer ชุดเดิมที่ตรวจสอบได้ ตัวเดียวกับที่ได้จาก `git clone https://github.com/ohm41321/luciazero.git && ./install.sh` เลือกช่องทาง**เดียว** — plugin หรือ classic — เพื่อไม่ให้ hook ถูกต่อสายซ้ำสองชั้น อยากเห็นหลักฐานก่อนติดตั้ง? `./demo.sh` สร้าง repo ฝังบั๊กให้คุณแก้ใน session ของตัวเองแล้วให้ grader แบบ offline ตัดสิน
44
+
45
+ ## ติดตั้งแล้วใช้ skill ไหนตอนไหน
46
+
47
+ ไม่ต้องท่องอะไร — doctrine กับ hook ทำงานเองอยู่เบื้องหลัง ส่วน skill มีไว้เรียกเฉพาะจังหวะ และก้าวแรกในทุก repository คือรัน `/luciazero-bootstrap` หนึ่งครั้ง เพื่อให้มีคำสั่ง verify ให้ทุกอย่างที่เหลือพิงได้ (ติดตั้งแบบ plugin ชื่อจะมี prefix: `/luciazero:done`, `/luciazero:debug`, …)
48
+
49
+ | จังหวะ | Skill | ทำอะไร |
50
+ |---|---|---|
51
+ | เข้า repository ครั้งแรก | `/luciazero-bootstrap` | หาหรือสร้างคำสั่ง verify, เพิ่ม smoke test 3–6 ตัว + ไฟล์ notes ของโปรเจกต์, พิสูจน์ว่า verify แดงได้จริง |
52
+ | บั๊กที่มองแวบแรกไม่ออก | `/debug` | reproduce ให้นิ่งก่อน, hypothesis ledger ที่ seed จากบทเรียนเก่า (`docs/lessons.md` + heuristics ข้าม repo), ปิดด้วย regression test ที่แดงก่อนแก้ |
53
+ | กำลังจะบอกว่า "เสร็จ" | `/done` | verify ระดับเต็มพร้อมยกบรรทัดชี้ขาด, อ่าน diff แบบผู้ไม่เชื่อ, เช็คความซื่อสัตย์ของ test ด้วย `revert-probe.sh`, รายงานฟอร์มตายตัว |
54
+ | ต้องหยุดทั้งที่งานยังไม่จบ | `/handoff` | เขียน capsule `HANDOFF.md`: เป้าหมาย, สถานะที่ verify แล้ว, คำสั่งถัดไปหนึ่งคำสั่งแบบพิมพ์ตามได้ |
55
+ | งานสาย "ทำให้เร็วขึ้น" | `/experiment` | ตั้ง metric + เกณฑ์ชนะก่อนแตะโค้ด, วัด baseline ซ้ำหลายรอบ, หนึ่งตัวแปรต่อรอบ, ตัวแพ้ถูก revert |
56
+ | หลังงานยากหรือ debug ยาว | `/retro` | route บทเรียนลง notes ของโปรเจกต์, ledger `docs/lessons.md` และ heuristics ข้าม repo; อ่าน stats log วินัยของตัวเอง |
57
+
58
+ agent `reviewer` ไม่ต้องเรียกชื่อเอง — `/done` จะ spawn ให้เมื่อ diff เสี่ยงพอ หรือพิมพ์ขอ "adversarial review" ตอนไหนก็ได้
59
+
60
+ ## สิ่งที่ได้
61
+
62
+ ไม่มี dependency ไม่มี runtime (ใช้ python3 เฉพาะ enforcement pack ซึ่งเป็น opt-in):
63
+
64
+ | ชิ้นส่วน | หน้าที่ | โหลดเมื่อไหร่ |
65
+ |---|---|---|
66
+ | `claude/luciazero.md` | Doctrine — กฎ 9 ข้อ | ตลอดเวลา ทุกโปรเจกต์ ทุก session |
67
+ | `skills/luciazero-bootstrap/` | ขั้นตอนทำ repo ให้พร้อมสำหรับ agent (มาพร้อม `scripts/detect.sh`) | เมื่อเรียก |
68
+ | `skills/debug/` | ขั้นตอน debug แบบตั้ง hypothesis ก่อนแก้ | เมื่อเรียก |
69
+ | `skills/done/` | พิธีปิดงาน (มาพร้อม `scripts/revert-probe.sh`) | เมื่อเรียก |
70
+ | `skills/handoff/` | state capsule ส่งต่อให้ session/agent ถัดไป | เมื่อเรียก |
71
+ | `skills/experiment/` | โปรโตคอลวัดผลสำหรับงาน optimize | เมื่อเรียก |
72
+ | `skills/retro/` | เก็บเกี่ยวบทเรียนลง notes ของโปรเจกต์ | เมื่อเรียก |
73
+ | `claude/agents/reviewer.md` | Subagent ผู้ตรวจเชิงหักล้าง | เมื่อเรียก (ก่อนประกาศ "เสร็จ") |
74
+ | `claude/hooks/` | Enforcement pack — hook เตือน verify, strict gate แบบ opt-in, statusline | Opt-in |
75
+ | `eval/` | A/B harness — 4 task บั๊กฝัง, grader พิสูจน์ตัวเองได้ | รันเอง (เสียเงิน API) |
76
+ | `demo.sh` | เดโม 2 นาที — บั๊กฝัง, session ของคุณเอง, grader เป็นกลาง | รันเอง |
77
+
78
+ เทียบกับ superpowers, SuperClaude, proof-loop และของ built-in ใน harness — รวมทั้งจุดที่เขาทำได้ดีกว่า: [docs/comparison.md](docs/comparison.md)
79
+
80
+ ## หน้าตาเวลาใช้งานจริง
81
+
82
+ เอาต์พุตจริงของสคริปต์ที่ ship มา ไม่ใช่ mockup — statusline โชว์สถานะ verify บนหน้าจอตลอดเวลา:
83
+
84
+ ```
85
+ Opus | ✎ unverified # แก้โค้ดแล้ว ยังไม่รัน verify เลย
86
+ Opus | ✅ verify 3m # verify ล่าสุดเขียว เมื่อ 3 นาทีก่อน
87
+ Opus | ❌ verify RED 40s # verify ล่าสุดแดง — ลูปยังไม่จบ
88
+ ```
89
+
90
+ จะจบ session ทั้งที่แก้โค้ดแล้วยังไม่ verify → โดนเตือนหนึ่งครั้ง:
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
+ ```
97
+
98
+ และใน strict mode (opt-in) verify ที่แดงจะ*บล็อก*การจบ session จริง ๆ พร้อมแนบหลักฐาน:
99
+
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:
103
+
104
+ test_totals ... FAIL: expected 14, got 8
105
+ ```
106
+
107
+ ## ติดตั้งแบบ classic & enforcement pack
108
+
109
+ `./install.sh` ทำสี่อย่าง: คัดลอก `claude/luciazero.md` → `~/.claude/luciazero.md`, skill ทั้งหก → `~/.claude/skills/`, reviewer agent → `~/.claude/agents/reviewer.md` (ถ้ามีฉบับที่คุณแก้เองจะ backup ให้ก่อน) และเติมบรรทัด `@luciazero.md` ลง `~/.claude/CLAUDE.md` มัน backup `CLAUDE.md` ก่อนแตะเสมอ รันซ้ำได้ปลอดภัย และไม่เขียนอะไรนอก `~/.claude/` เลย — สี่ขั้นตอนนี้ก็คือการติดตั้งมือทั้งหมดด้วย
110
+
111
+ ### Enforcement pack (opt-in)
112
+
113
+ ```bash
114
+ ./install.sh --with-hooks # ต้องมี python3
115
+ ```
116
+
117
+ ต่อสคริปต์สองตัวเข้า `~/.claude/settings.json` (backup ให้ก่อน, merge แบบ additive และ idempotent): **Stop hook เตือน verify** — ถ้าแก้โค้ดแล้วไม่มีคำสั่งแนว verify รันเลยหลังการแก้ล่าสุด การจบ session จะโดนเตือนหนึ่งครั้งตามตัวอย่างข้างบน เตือนครั้งเดียว ไม่วนลูป และ fail open — กับ **statusline** (ถ้าคุณมีของตัวเองอยู่แล้ว มันจะไม่แตะ) Stop hook ยังจดหนึ่งบรรทัดต่อผลลัพธ์การจบ session (`stop-clean` / `nudge` / `strict-block`) ลง `luciazero-stats.log` ใน config dir — อยู่ในเครื่องเท่านั้น เพดาน ~250 บรรทัด fail-open — ให้ `/retro` อ่านแล้วแปลงช่องโหว่วินัยที่เกิดซ้ำเป็นบทเรียนที่บันทึกไว้
118
+
119
+ อะไรนับเป็น verify ตัดสินด้วย regex กว้าง ๆ (test.sh, pytest, `npm test`, `cargo test`, …) — override ได้ด้วย `LUCIAZERO_VERIFY_REGEX` หรือดีกว่านั้น ตั้งคำสั่งจริงของ repo ด้วย `LUCIAZERO_VERIFY_CMD` (เช่นในบล็อก `env` ของ `.claude/settings.local.json` ประจำ repo): ในโหมด exact จะนับเฉพาะคำสั่งที่*เป็น*หรือ*ขึ้นต้นด้วย*มันเท่านั้น `cat test.sh` จึงทำให้สถานะเขียวปลอมไม่ได้ การเขียนไฟล์เอกสาร (`*.md` และพวก — `LUCIAZERO_DOC_REGEX`) จะไม่ re-arm การเตือน เพราะ skill สายปิดงานล้วนเขียน notes *หลัง* verify เขียวรอบสุดท้าย hook `SessionStart` จะพิมพ์ pointer หนึ่งบรรทัดเมื่อโปรเจกต์มี capsule `HANDOFF.md` ค้างอยู่ (เตือนความเก่าเมื่อเกิน `LUCIAZERO_HANDOFF_STALE_DAYS` ค่าเริ่มต้น 7 วัน) — ชี้ตำแหน่งเท่านั้น ไม่เอาเนื้อหามาใส่
120
+
121
+ **Strict mode (opt-in ซ้อน opt-in)** ตั้ง `LUCIAZERO_STRICT_VERIFY_CMD` เป็นคำสั่ง verify *เร็ว*ของ repo — ใน settings **ส่วนตัว**เท่านั้น ห้ามอยู่ในไฟล์ที่ commit ข้อจำกัดที่บอกตรง ๆ: hook อ่านจาก environment variable และแยกไม่ออกว่า settings ชั้นไหนตั้งมันมา — `env` ใน `.claude/settings.json` ที่ commit มากับ repo ก็ไปถึงมันเช่นกัน — เพราะฉะนั้นให้ถือว่า repo ที่ ship ตัวแปรนี้มาเป็น repo ประสงค์ร้าย และลบตัวแปรนั้นทิ้งก่อนเริ่มทำงานใน repo นั้น เมื่อจะจบ session hook จะรันคำสั่งนั้นจริง ๆ (เว้นแต่สถานะเขียวอยู่แล้วหลังการแก้ล่าสุด) แล้ว**บล็อกการจบ**เมื่อแดง พร้อมยกเอาต์พุตที่พังให้ดู มี hard timeout ตัดจบเด็ดขาดผ่าน `LUCIAZERO_STRICT_TIMEOUT` (ค่าเริ่มต้น 120 วินาที); ทุก error ภายใน — timeout, คำสั่งหาย, JSON พัง — ถอยกลับเป็นการเตือนธรรมดา ไม่มีทางกลายเป็นการบล็อก และ continuation หลังโดนบล็อกจะไม่โดนบล็อกซ้ำ (`stop_hook_active`): นี่คือลูกระนาดพร้อมหลักฐาน ไม่ใช่กำแพง
122
+
123
+ ### ตรวจ อัปเดต ถอน
124
+
125
+ `./install.sh --status` คือ health check แบบอ่านอย่างเดียว: doctrine, skill, agent, บรรทัด import, เวอร์ชัน และ — เมื่อติดตั้ง enforcement pack — เช็คว่าไฟล์ hook รันได้*และถูกต่อสายจริง* (hook ออกแบบให้ fail open การติดตั้งที่พังจึงเงียบสนิทถ้าไม่มีตัวเช็ค) คืนค่าไม่เป็นศูนย์ถ้าชิ้นหลักหายไป อัปเดตด้วย `git pull && ./install.sh` (idempotent; sidecar เวอร์ชันทำให้ `--status` บอกได้เมื่อของที่ติดตั้งเก่ากว่า checkout) `./uninstall.sh` ลบสคริปต์และเก็บกวาดเฉพาะ entry ของเราใน settings โดยจับคู่ด้วย path เต็ม — รันจาก checkout ที่ใหม่อย่างน้อยเท่ากับตัวที่ใช้ติดตั้ง
126
+
127
+ ### Codex CLI
128
+
129
+ `./install-codex.sh` (ถอนด้วย `./uninstall-codex.sh`) — เนื้อหาเดียวกัน source เดียว แปลงตอนติดตั้ง:
130
+
131
+ | ชิ้นส่วน | ไปอยู่ใน Codex เป็น |
132
+ |---|---|
133
+ | Doctrine | บล็อกคั่นด้วย marker ใน `~/.codex/AGENTS.md` (ติดตั้งซ้ำจะแทนที่ตรงที่เดิม) |
134
+ | Skill ทั้งหก | `~/.codex/skills/` — ฟอร์แมต `SKILL.md` เดียวกัน คัดลอกตรง ๆ |
135
+ | Agent `reviewer` | `~/.codex/skills/reviewer/` — Codex ไม่มี subagent จึง ship เป็น skill |
136
+ | Enforcement pack | ไม่ติดตั้ง — Codex ไม่มี hook/statusline |
137
+
138
+ เคารพ `CODEX_HOME`, backup `AGENTS.md`, idempotent, ไม่เขียนอะไรนอกไดเรกทอรีของ Codex — doctrine และ skill เขียนแบบเป็นกลางต่อแพลตฟอร์ม ข้อความชุดเดียวกันจึงใช้ได้ทั้งสอง CLI โดยไม่ต้องแปล
139
+
140
+ ## Doctrine พูดว่าอะไร
141
+
142
+ กฎ 9 ข้อ 4 กลุ่ม ฉบับเต็มอยู่ใน `claude/luciazero.md`
143
+
144
+ **Ground truth** — "เสร็จ" ต้องพิสูจน์ด้วย exit code และการรันที่ไม่ได้เกิดขึ้นต้องรายงานตามนั้นตรง ๆ; ไม่มีคำสั่ง verify คือบั๊กแรก; ห้าม weaken การตรวจใด ๆ เพื่อให้เขียว
145
+
146
+ **Loop** — debug เริ่มด้วย hypothesis และคำสั่งที่จะหักล้างมัน ไม่ใช่การแก้โค้ด แล้ว reproduction กลายเป็น regression test; เข้า repo ที่ไม่คุ้นให้ orient ก่อนแก้ — CI คือแหล่งความจริงที่ซื่อสัตย์; ก้าวที่เล็กที่สุดที่ย้อนกลับได้; อ่าน diff สุดท้ายแบบผู้ไม่เชื่อ — diff เสี่ยงต้องผ่าน review เชิงหักล้างอิสระ
147
+
148
+ **Memory** — ห้ามเดินเข้าทางตันเดิมสองครั้ง: จดสิ่งที่โค้ดบอกเองไม่ได้ (null result, footgun) และอ่าน notes ของโปรเจกต์ก่อนทำงานในบริเวณที่ notes ครอบคลุม
149
+
150
+ **Autonomy** — หยุดแล้วถามด้วยคำถามที่ตัดสินได้ชัดเจน ก่อนการกระทำเดิมพันสูงหรือย้อนกลับไม่ได้ (ลบข้อมูล, deploy, production, public contract, เงิน, ออกนอก scope); อย่างอื่นเดินหน้าต่อ รวมข้อสงสัยเป็นคำถามคมคำถามเดียว; ทำให้ครบทั้ง scope และบอกชื่อสิ่งที่เว้นไว้
151
+
152
+ มันสั้นโดยตั้งใจ และ `test.sh` บังคับเพดานจำนวนคำของมัน เพราะทุกบรรทัดกินค่า context ทุก turn ของทุก session ข้อที่แค่เล่าซ้ำสิ่งที่ harness ปี 2026 บังคับเป็นค่า default อยู่แล้ว ถูกตัดออก; CHANGELOG บันทึกทุกการตัดพร้อม default ที่มันพึ่งพา
153
+
154
+ ## Skill แต่ละตัวทำอะไร
155
+
156
+ `/luciazero-bootstrap` พา repository ผ่าน 6 เฟส: **detect** (รัน `scripts/detect.sh` สแกนหลักฐานในคำสั่งเดียว แล้วอ่าน config CI เอง — CI คือแหล่งความจริง; สคริปต์เสนอตัวเลือก ส่วน agent เป็นคนตัดสิน), **ตั้งคำสั่ง verify** (ใช้ตัวเดิมถ้ามี ไม่มีค่อยสร้างตัวจริงที่เล็กที่สุด: exit ไม่เป็นศูนย์เมื่อพัง รันจบเอง รัน offline และ*จับเวลาหนึ่งครั้ง* — ตัวเลขตัดสินว่าหนึ่งหรือสองระดับ; monorepo ให้ scope ระดับเร็ว), **smoke tests** (3–6 ตัวที่จับความพังระดับหายนะ — ไม่ใช่ coverage และบอกไว้ตรง ๆ), **guardrails** (เอาเฉพาะ hook ที่คุ้มค่าตัวเอง; ฝั่ง Codex เข้ารหัสเป็นคำสั่งใน `AGENTS.md` แทน), **notes ของโปรเจกต์** (เฉพาะสิ่งที่อ่านโค้ดแล้วไม่มีทางรู้) และ **พิสูจน์** (รันระดับเร็วสองครั้ง — เขียวที่ไม่ซ้ำคือ flake; พังบรรทัดที่ cover จริง ยืนยันว่าแดง แล้วกู้คืน) ทั้งหมด language-agnostic: มัน detect ไม่ใช่ assume
157
+
158
+ `/debug` ขยายกฎ hypothesis สำหรับบั๊กที่มองแวบแรกไม่ออก: reproduce ให้ deterministic ก่อน, ย่อ reproduction, จด hypothesis ledger ให้เห็น ๆ (แต่ละรายการระบุคำสั่งที่จะหักล้างมัน), เปลี่ยนหนึ่งตัวแปรต่อรอบ, revert การแก้ที่ไม่ผ่าน, ปิดงานด้วย regression test ที่แดงก่อนแก้และเขียวหลังแก้ ledger จะ seed ตัวเองจากประสบการณ์ที่บันทึกไว้ก่อน — grep อาการใน `docs/lessons.md` ของ repo และ `luciazero-heuristics.md` ข้าม repo ก่อนคิด hypothesis ใหม่; เจอของเก่าตรง = ขึ้นเป็น H1 แต่ยังต้องพิสูจน์
159
+
160
+ `/done` คือพิธีปิดงาน: verify ระดับเต็มพร้อมยกบรรทัดชี้ขาด, อ่าน diff สุดท้ายแบบผู้ไม่เชื่อ, review เชิงหักล้างอิสระเมื่อ diff สมควรได้, เช็ค scope โดยระบุชื่อสิ่งที่เว้นไว้ และฟอร์มรายงานตายตัว คำถามความซื่อสัตย์ของ test — *ถ้า revert การแก้ test ใหม่จะแดงไหม?* — มีกลไกให้ใช้จริง: `scripts/revert-probe.sh` ที่แถมมา checkout โค้ดเก่าลง git worktree ชั่วคราว วางเฉพาะไฟล์ test ที่เปลี่ยนทับลงไป รันคำสั่ง verify ของคุณที่นั่น แล้วกลับผล (exit 0/1/2 = กัดจริง/test หลอก/ประเมินไม่ได้)
161
+
162
+ `/handoff` เขียน state capsule (`HANDOFF.md`) เมื่อ session จบทั้งที่งานยังไม่จบ: เป้าหมาย, สถานะที่ verify แล้ว, คำสั่งถัดไปหนึ่งคำสั่งแบบพิมพ์ตามได้เลย, hypothesis ที่ยังเปิด/หักล้างแล้ว, กับระเบิดที่รู้ตำแหน่ง session ถัดไป — หรือ harness อีกฝั่ง — อ่าน, verify ซ้ำกับ tree จริง, แล้วลบทิ้ง
163
+
164
+ `/experiment` คือโปรโตคอลวัดผลสำหรับงาน "ทำให้เร็วขึ้น": นิยาม metric และเกณฑ์ชนะก่อนแตะโค้ด, วัด baseline ซ้ำหลายรอบ, หนึ่งตัวแปรต่อหนึ่งการทดลอง, บันทึกคำตัดสินลง `docs/experiments.md` — ที่ซึ่ง null result มีค่าเท่าชัยชนะ และตัวที่แพ้ถูก revert ทันที
165
+
166
+ `/retro` ปิดลูปของกฎ*ห้ามเดินเข้าทางตันเดิมสองครั้ง*: หลังงานยากมันกรอง session เอาเฉพาะสิ่งที่**อ่านโค้ดแล้ว agent ในอนาคตไม่มีทางรู้** (null result, footgun, ความประหลาดของ environment), route บทเรียนที่จริงสำหรับ repo ลง notes ของโปรเจกต์ ส่วนข้อเท็จจริงเฉพาะเครื่องลง memory ของ harness (ไม่ commit เด็ดขาด), อัปเดต notes เดิมแทนการเขียนซ้ำ และลบ notes ที่ถูกพิสูจน์แล้วว่าผิด คลังเรียนรู้สามชั้นทำให้มันทบต้นข้ามเวลา: บั๊กที่ debug จบแล้วลง `docs/lessons.md` ของ repo ในรูปแบบตายตัวที่ grep ได้ (อาการ → สาเหตุ → proven-by → วิธีแก้) ซึ่ง `/debug` จะอ่านรอบหน้า; บทเรียนที่จริงทุก repository ลง `luciazero-heuristics.md` ใน config dir (บรรทัดละหนึ่งบทเรียน เพดานแข็ง 100 บรรทัด — ไฟล์ heuristics ที่โตไม่หยุดจะกลายเป็นภาษี context ที่ pack นี้เกิดมาเพื่อกันเอง); และ stats log ของ enforcement pack แปลง nudge ที่โดนซ้ำ ๆ เป็นบทเรียนพฤติกรรม การถอนการติดตั้งเก็บทั้งสามไฟล์ไว้ — มันคือข้อมูลที่เรียนรู้มา retro ที่ว่างเปล่าก็เป็น retro ที่ถูกต้อง — และความรู้เลิกระเหยไปตอน session จบ
167
+
168
+ ## ด่านหักล้าง: agent `reviewer`
169
+
170
+ exit code จับ *ผ่านเทสต์แต่ผิด* ไม่ได้ diff ที่เสี่ยง doctrine จึงต้องการ review เชิงหักล้างอิสระ: บน Claude Code คำสั่ง `/code-review` ในตัวแรงกว่าและถูกเลือกก่อนเมื่อมี; agent `reviewer` ที่ ship มาคือ fallback แบบพกพา และเป็น reviewer เดียวบน Codex อ่านอย่างเดียว ถูกสั่งให้**หักล้าง**การแก้ รันบนโมเดลเดียวกับ thread หลัก (`model: inherit`) และรายงาน `No findings.` แทนการมโนหาเรื่อง
171
+
172
+ ## บันทึกการออกแบบ
173
+
174
+ **ทำไมเป็นไฟล์ ไม่ใช่ hook** hook มีไว้บังคับของที่ mechanical และ deterministic; doctrine คือวิจารณญาณ และวิจารณญาณอยู่ใน context Claude Code re-inject `CLAUDE.md` หลัง compaction อยู่แล้ว — คันโยกกัน drift ตัวจริงคือทำ doctrine ให้เล็ก ซึ่ง `test.sh` บังคับไว้
175
+
176
+ **ทำไม doctrine กับ skill แยกกัน** doctrine ต้องถูกพอที่จะพกทุก turn; procedure ยาวและใช้เฉพาะจังหวะ จึงโหลดเมื่อเรียก รวมกันเมื่อไหร่คุณจะจ่ายค่า procedure ตลอดเวลา
177
+
178
+ **Plugin เข้ากับหลักนี้ยังไง** plugin ไม่มีทาง import ไฟล์เข้า `CLAUDE.md` ช่องทาง plugin จึงส่ง doctrine เป็น context ผ่าน `SessionStart` — ยอมรับได้เพราะข้อความถูกคุมเพดานจำนวนคำ และมี guard ให้เงียบเมื่อการติดตั้งแบบ classic import มันอยู่แล้ว ตัวติดตั้ง classic ยังเป็นช่องทางอ้างอิง; plugin ยอมสละ statusline และ `--status` เพื่อแลกกับการติดตั้งด้วยคำสั่งเดียวและการอัปเดตผ่าน marketplace
179
+
180
+ **Settings ของโปรเจกต์อยู่กับโปรเจกต์** `examples/project-settings.example.json` โชว์รูปแบบราย repo — allowlist สิทธิ์เพื่อไม่ให้ลูป verify สะดุด และ guard แบบ inert สำหรับกันการกดเงียบ check ซึ่ง mechanize กฎ "ห้าม weaken การตรวจเพื่อให้เขียว" คัดลอกไปใส่ `.claude/settings.json` ของ repo; อย่าเอาคำสั่งของโปรเจกต์ไปใส่ settings ส่วนกลาง
181
+
182
+ **Agentic CI เป็นลูปวินิจฉัยเท่านั้น** `examples/luciazero-ci.example.yml` (inert, มี REPLACE-ME กั้น) โพสต์การวินิจฉัยต้นเหตุของ agent ลง PR เมื่อ CI แดง มัน push หรือแก้โค้ดไม่ได้ (`contents: read`, allowlist ไม่มี Bash, ไม่มี credentials); สิทธิ์เขียนเดียวคือโพสต์คอมเมนต์วินิจฉัยที่จำกัดขนาด มันไม่ auto-fix: agent ที่แก้ CI แบบตาบอด ship การแก้ที่ดูสมเหตุสมผลแต่ผิด
183
+
184
+ <p align="center">
185
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia-laptop.png" width="240" alt="Lucia นั่งไล่ eval harness บนโน้ตบุ๊ก">
186
+ </p>
187
+
188
+ **Setup วัดตัวเอง** `eval/` คือ A/B harness เล็ก ๆ: task บั๊กฝังชุดเดียวกัน รันแบบมีและไม่มี doctrine แล้ว grade แบบ offline ด้วยเกณฑ์พฤติกรรม สี่ task แต่ละตัวจิ้มกฎคนละข้อ — slugify (วินัย regression test), red-suite (แรงล่อให้บิด test เข้าหาบั๊ก), flaky-report (ทำความล้มเหลวแบบมา ๆ หาย ๆ ให้ deterministic), pipeline (แก้ต้นเหตุ vs แปะที่อาการ ตัดสินด้วย diff locality) CI พิสูจน์ grader ทุกตัวสามทางทุก push: `reference/` ต้องผ่าน, `project/` ที่ยังไม่แก้ต้องตก, tree โกง `gamed/` ต้องถูกปฏิเสธ `eval/run.sh --runs N` + `eval/report.sh` สร้างตาราง pass-rate รายเกณฑ์; ดู `eval/README.md` รวมทั้ง honesty box เรื่อง n น้อย
189
+
190
+ ## ความปลอดภัย
191
+
192
+ hook รันคำสั่งบนเครื่องคุณโดยอัตโนมัติ ไฟล์ settings ตัวอย่าง inert โดยออกแบบ — ทุก hook ในนั้นถูก comment ไว้และต้องแก้เองก่อนจึงจะทำอะไร อ่าน hook ทุกตัวก่อนเปิดใช้ และอย่าเปิด hook ที่ push, deploy, ลบ หรือเขียนนอก repository
193
+
194
+ ## การพัฒนา repo นี้
195
+
196
+ `./test.sh` คือคำสั่ง verify ของ repo นี้เอง — doctrine บอกว่าไม่มีคำสั่ง verify คือบั๊กแรก repo นี้จึงต้องผ่านกฎของตัวเอง มันครอบคลุม shell syntax + shellcheck, state machine ของ hook (รวม strict gate), manifest ของ plugin + npm, grader ทุกตัวพิสูจน์ว่าแดงได้ *และ*เขียวได้ *และ*กันโกง, `revert-probe.sh` ใน git fixture ชั่วคราว, `demo.sh` และ cycle ติดตั้ง → ติดตั้งซ้ำ → ถอน ครบทั้งสอง harness ใน config dir แบบ sandbox — ไม่แตะ `~/.claude/` หรือ `~/.codex/` จริงของคุณเด็ดขาด CI รันทุก push; การ tag `vX.Y.Z` เผยแพร่ GitHub Release ดู `CONTRIBUTING.md` และ [docs/publishing.md](docs/publishing.md)
197
+
198
+ ```
199
+ $ ./test.sh
200
+ PASS all checks green
201
+ ```
202
+
203
+ <p align="center">
204
+ <img src="https://raw.githubusercontent.com/ohm41321/luciazero/main/docs/assets/lucia-cheer.png" width="240" alt="Lucia ฉลองเทสต์เขียวครบทุกด่าน">
205
+ </p>
206
+
207
+ ## ผลิตภัณฑ์ในเครือ & สนับสนุน
208
+
209
+ Luciazero ใช้มาสคอตร่วมกับ [Lucia](https://lucia-discord-bot.vercel.app) — Discord bot ภาษาไทยที่มี AI chat, เปิดเพลง, มินิเกม และระบบสะสมการ์ดกาชา
210
+
211
+ ถ้า Luciazero ช่วยประหยัดรอบ review ของคุณได้ [สนับสนุนโปรเจกต์ได้ที่นี่](https://easydonate.app/itsathitz) 💚
212
+
213
+ ## License
214
+
215
+ [MIT](LICENSE)
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // Thin router to the bundled bash installers. Everything happens only when the
3
+ // user explicitly runs `npx luciazero` — this package has no lifecycle scripts.
4
+ //
5
+ // npx luciazero [--with-hooks|--status] -> install.sh (Claude Code)
6
+ // npx luciazero codex -> install-codex.sh
7
+ // npx luciazero uninstall -> uninstall.sh
8
+ // npx luciazero uninstall-codex -> uninstall-codex.sh
9
+ const { spawnSync } = require("node:child_process");
10
+ const path = require("node:path");
11
+
12
+ if (process.platform === "win32") {
13
+ console.error(
14
+ "luciazero needs bash (macOS, Linux, or WSL). On Windows, run it inside WSL: bash install.sh"
15
+ );
16
+ process.exit(1);
17
+ }
18
+
19
+ const ROUTES = {
20
+ install: "install.sh",
21
+ codex: "install-codex.sh",
22
+ uninstall: "uninstall.sh",
23
+ "uninstall-codex": "uninstall-codex.sh",
24
+ };
25
+
26
+ const args = process.argv.slice(2);
27
+ const route = Object.prototype.hasOwnProperty.call(ROUTES, args[0]) ? args.shift() : "install";
28
+ const script = path.join(__dirname, "..", ROUTES[route]);
29
+
30
+ const result = spawnSync("bash", [script, ...args], { stdio: "inherit" });
31
+ if (result.error) {
32
+ console.error("luciazero: could not run bash: " + result.error.message);
33
+ process.exit(1);
34
+ }
35
+ process.exit(result.status === null ? 1 : result.status);
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: reviewer
3
+ description: Adversarial code reviewer. Spawn before declaring a non-trivial change done, or when asked to review a diff, branch, or PR. Tries to refute the change — hunts specifically for what the automated checks do not cover. Read-only; never edits files. If the harness offers a built-in adversarial review command (Claude Code has /code-review), prefer it; use this agent when none exists or a second in-session opinion is wanted.
4
+ tools: Read, Grep, Glob, Bash
5
+ model: inherit
6
+ ---
7
+
8
+ You are an adversarial code reviewer. Your job is to **refute** the change, not to approve it. Assume the diff contains at least one real problem and hunt for it; praise is noise and is forbidden.
9
+
10
+ ## Input
11
+
12
+ You are given a diff, a branch, a PR, or a list of changed files. If given a branch or nothing specific, derive the diff yourself (`git diff`, `git diff main...HEAD`, `git show`). Read enough surrounding code to judge each hunk in context — a hunk that looks fine in isolation often breaks an invariant defined two screens up.
13
+
14
+ ## What to hunt
15
+
16
+ Automated checks already cover the happy path. Hunt what they do not:
17
+
18
+ - **Edge cases** — empty input, zero, negative, unicode, max length, first/last element, concurrent access
19
+ - **Error paths** — what happens when the call fails, the file is missing, the network drops; are errors swallowed?
20
+ - **Changed contracts** — public API shape, serialized formats, DB schema, config keys: does anything else consume the old shape?
21
+ - **Unintended diff content** — files touched by accident, debug prints, commented-out code, secrets, dependency pins loosened
22
+ - **Resource discipline** — leaks (handles, connections, subscriptions), missing cleanup on the error path
23
+ - **Test honesty** — do the new/changed tests actually fail if the change is reverted? Tests that assert nothing, or were weakened to pass, are findings.
24
+ - **Security** — injection via interpolated input, path traversal, secrets in code or logs
25
+
26
+ ## Rules
27
+
28
+ - **Verify before reporting.** Read the actual code for each suspected finding. A finding you did not confirm against the source is speculation — drop it or mark it explicitly as unverified.
29
+ - Run cheap read-only commands when they settle a question (`git log` for context, the test suite if it is fast). Never edit, never commit, never push.
30
+ - No style or formatting nits unless they change meaning.
31
+ - Stay inside the diff's scope; pre-existing problems you notice go in one short "outside scope" line at the end, not as findings.
32
+
33
+ ## Output
34
+
35
+ One line per finding, most severe first:
36
+
37
+ ```
38
+ path:line — severity — problem. Concrete fix.
39
+ ```
40
+
41
+ Severity: `blocker` (wrong result, data loss, security) / `major` (breaks an edge case or contract) / `minor` (works, but fragile).
42
+
43
+ If, after a genuine hunt, nothing survives verification: report exactly `No findings.` plus one sentence on what you checked. Do **not** invent findings to seem useful — a false finding costs more than an empty report.
@@ -0,0 +1,33 @@
1
+ {
2
+ "hooks": {
3
+ "PostToolUse": [
4
+ {
5
+ "matcher": "Edit|Write|NotebookEdit",
6
+ "hooks": [
7
+ { "type": "command", "command": "LUCIAZERO_CHANNEL=plugin ${CLAUDE_PLUGIN_ROOT}/claude/hooks/luciazero-verify.sh edit" }
8
+ ]
9
+ },
10
+ {
11
+ "matcher": "Bash",
12
+ "hooks": [
13
+ { "type": "command", "command": "LUCIAZERO_CHANNEL=plugin ${CLAUDE_PLUGIN_ROOT}/claude/hooks/luciazero-verify.sh bash" }
14
+ ]
15
+ }
16
+ ],
17
+ "Stop": [
18
+ {
19
+ "hooks": [
20
+ { "type": "command", "command": "LUCIAZERO_CHANNEL=plugin ${CLAUDE_PLUGIN_ROOT}/claude/hooks/luciazero-verify.sh stop" }
21
+ ]
22
+ }
23
+ ],
24
+ "SessionStart": [
25
+ {
26
+ "hooks": [
27
+ { "type": "command", "command": "LUCIAZERO_CHANNEL=plugin ${CLAUDE_PLUGIN_ROOT}/claude/hooks/luciazero-verify.sh session" },
28
+ { "type": "command", "command": "LUCIAZERO_CHANNEL=plugin ${CLAUDE_PLUGIN_ROOT}/claude/hooks/luciazero-verify.sh doctrine" }
29
+ ]
30
+ }
31
+ ]
32
+ }
33
+ }