Repository navigation
Releases: cyb213/Lab-Zero
Release list
Lab Zero v1.21.0 — Codex helper agents, re-wire hint, model-invocable ceremonies
Updating to this release: from v1.20.0, one bash update.sh run is enough. From an older version, follow the v1.20.0 note below (two runs), because your current updater predates the one-run fix. If you use Codex, re-run the harness wiring afterwards — from this release on, the updater prints the exact line (see below).
-
The two helper agents now work on Codex too.
bootstrap.sh --harness …,codexgenerates Codex versions oflab-readerandlab-revieweras.codex/agents/lab-reader.tomland.codex/agents/lab-reviewer.toml, from the same.claude/agents/lab-zero/files Claude Code uses. Like the rest of.codex/, they're generated on your machine and git-ignored — nothing new is committed. Three limits, stated plainly:- Read-only by instruction only. On Claude Code the helpers are limited to read/search tools. On Codex, a helper runs with your session's permissions, and Lab Zero sets no sandbox for it (it ships no permission settings on either harness). Its instructions tell it not to edit or run state-changing commands; nothing enforces that.
- Codex starts a helper only when asked — by you, or by a skill or project instruction. In our live test,
/lab-plan's review step pickedlab-revieweron its own; forlab-reader, ask for it by name. - Trust the project first. In an untrusted project Codex loads none of them — the spawn tool doesn't even offer an agent type. A one-off
-c projects.…trust_leveloverride on the command line was not enough in our test; the project's trust entry in~/.codex/config.tomlwas.
They inherit your session's model and reasoning effort (no model or effort is pinned). Each generated file's first line says it was generated and names its own path. Re-wiring overwrites or removes only files whose first line names them, and dropping Codex removes only those. A file you wrote yourself under the same name is left alone, with a warning. To customize a helper, copy it to a new name — the copy is yours and is never touched. Live-tested on
codex-cli 0.153.4(modelgpt-5.6-sol):lab-readeranswered by name with correctfile:linecitations, and/lab-planspawnedlab-reviewer(confirmed in Codex's own session log asagent_role: lab-reviewer), which inherited the session's model, effort and sandbox. Codex's agent format may still change. -
The helpers' own instructions no longer name Claude-only tools. They said "the toolset is Read, Grep, and Glob only", which isn't true on Codex. They now say: read, search, and list files — no edits, no fixes, no state-changing commands.
-
Both updaters tell Codex users exactly how to re-wire. The Codex layer is git-ignored, so
update.shnever refreshes it. When your.lab/harnessesincludescodex, the updater's last lines now print the exact command, with an absolute path and your recorded harness set, e.g.LAB_BOOTSTRAP_SKIP_ENGINE=1 bash /path/to/bootstrap.sh --harness claude,codex(wiring only — no reinstall, no reindex). The project updater's old hint was relative and said--harness codex, which would have dropped Claude from aclaude,codexworkspace's recorded set; it's replaced. The Lab's updater had no hint at all. -
The agent can now start
/audit,/discover-skillsand/review-correctionsitself. They carrieddisable-model-invocation: true, which Codex ignores — so on Codex they were already model-invocable, while on Claude Code the flag also blocked the agent from starting them even when you asked for one. The flag is gone, so both harnesses behave the same, like/lab-planand/broalready did. You can still run each by name as before. One side effect: the session-start reminders ("run/review-corrections…", "run/discover-skills…") may now lead the agent to start that ceremony itself at the start of a session. -
Calmer wording in
/wrapand/discover-skills. Recent models (GPT-6 Astra and current Claude alike) can over-react to capitalized, emphatic instructions./wrap's drift-gate line, its two "do NOT"s,/discover-skills' worthiness bar, its anti-pattern heading, and its description now say the same things in plain case. The two real stop-gates in/wrapand the oneNEVERin/review-correctionsare unchanged.
Lab Zero v1.20.0 — helper agents, one-run updater, report-all reviews, curated seeding
Updating to this release: run bash update.sh twice. This release adds a new machinery folder, and the update.sh you already have only learns about new folders from the copy it downloads — so the first run fetches the new updater and the second run delivers the rest. In a graduated project, commit between the two runs (git add -A && git commit -m "lab-zero update") — otherwise the second run lists the first run's files as uncommitted changes about to be overwritten; that warning is harmless here, and pressing Ctrl-C at it stops the lanes from arriving. After the first run, --check already reports v1.20.0, so check the result instead: ls .claude/agents/lab-zero/ should show lab-reader.md and lab-reviewer.md. If it doesn't, run bash update.sh again. From this release on, one run is enough (see the first item below).
-
update.shnow finishes in one run, even when a release adds something new. A running updater worked from the list of machinery paths it started with, so a path added upstream arrived only on your next run. Now, if the updater itself changed during the run, it restarts the new copy once, with your original arguments, and that pass picks up anything new. It restarts at most once (a guard variable stops any loop), never in--checkmode, and in a project'supdate.shthe second pass doesn't repeat the "uncommitted changes will be overwritten" warning for files the first pass just wrote. Tested on bash 5; not yet exercised on bash 3.2 (the macOS default). If the restart ever stops early there, runningbash update.shonce more completes the update. -
Two read-only helper agents ship with the engine (Claude Code).
lab-reader(Sonnet) answers a question from the files with a short cited answer and marks anything it couldn't confirm, with where it looked.lab-reviewer(Opus) runs an adversarial pass — risk, feasibility, scope, or a diff — and reports every finding with severity, confidence andfile:line, leaving the ranking to you. Both can only read, search and list files. Each one's description says when to use it and that it is not for re-checking your own work. They live in.claude/agents/lab-zero/, which is the only part of.claude/agents/the updater touches — agents you write yourself stay yours, andcontribute.shnever sends anything under.claude/agents/ortemplate/.claude/agents/upstream. Codex: these are Claude Code agent files, and Codex doesn't read them — the helpers change nothing for Codex. (The skill changes below do reach Codex.) If a helper is ever renamed or withdrawn, that release's notes will carry thegit rmline, because updating never deletes. -
Reviews now report everything, then filter.
/auditand/discover-skillsused to cap how many findings they reported (about 8 per file and about 6 candidates per pass). Current models can follow a cap like that literally and report less, not just show less. Now they inventory everything first, then show a ranked short view, and the written report lists every item left out of that view with a one-line reason. An unverifiable/audititem goes under Unverified leads with where it looked, and is never acted on until a fresh pass verifies it./discover-skillsrecords overflow asDEFERRED, so the next sweep looks at it again instead of treating it as settled. A "nothing found" result now names what was checked./lab-plan's reviewers report every finding too, and the consolidation step lists each one it drops, with the reason. -
/lab-planno longer asks projects to guard a "shipped engine". Its list of changes that need a plan was written for the Lab Zero factory. It now reads: code or config others depend on (a published package, a deployed service, a shipped template), a hook, security or auth, user data, a release, or a change spanning several files or systems. It also points at your project constitution asAGENTS.md/CLAUDE.md, and/auditno longer names a Claude-specific tool. -
A new project's memory starts with the starter habits only.
new-project.shused to copy your Lab's whole memory into each project it graduated — Lab-only memories and facts frozen on the day of stamping included. It now seeds exactly the curatedmemory-seed/starter set, and never overwrites a file that's already there. To also copy your Lab's own memories, pass--seed-from-lab(same no-overwrite rule; your Lab'sMEMORY.mdindex is not copied over the starter one, so those extra files won't be listed in it).--no-seedstill skips seeding./new-projectnow describes this, and correctly says the purpose goes into the project'sAGENTS.md. On an existing install: this affects projects you graduate from now on; existing projects' memory is untouched.
Lab Zero v1.19.1 — template purpose scaffolding cleanup
Template cleanup — nothing changes for existing projects.
The project template's "What this is" section carried a leftover instruction telling you to
write a purpose paragraph that new-project.sh had already filled in from your /kickoff
answer. Removed.
- New projects only.
AGENTS.mdis part of your personal layer, soupdate.shnever
overwrites it — existing workspaces are unaffected and need no action. - No machinery, script, or hook changed. Constitution-drift baselines are byte-identical, so
no existing project gains a drift warning.
Lab Zero v1.19.0 — tracking density warnings + size-gate SIGPIPE fix
-
Your tracking files now warn you when an entry is growing into a document. Two advisory checks join the pre-commit hook. The first reads the rows a commit newly adds to
Log/TASKS.mdand names any over 200 bytes — TASKS is a dashboard, and a row that has become a paragraph belongs inSessions/,Log/plans/orDECISIONS.mdinstead. The second reads wholly-new## D-entries inLog/DECISIONS.mdand names any over 8 KB. Both are warn-only and never block: existing rows and existing entries are never flagged, so neither can turn your backlog into recurring noise, and editing a line inside an entry you already wrote stays silent. Thresholds areLAB_ROW_LEN_WARN(default 200) andLAB_ENTRY_SIZE_WARN_KB(default 8). Lengths are counted in bytes underLC_ALL=C, so an em-dash costs 3 — deliberate, because awk implementations disagree about what a "character" is, and a threshold that moves between machines is worse than one that is slightly strict. The whole block is wrapped so a failure inside it cannot stop your commit: the worst case is that the advisory silently does not run, and the shipped suite proves it by deliberately breaking the check and asserting the commit still succeeds. On an existing install:update.shdelivers both, no config change needed. Two limits worth knowing: the checks live inscripts/, so they reach every project that updates — but the one-line note inLog/TASKS.mdthat documents the row rule is part of your ownLog/, which no updater ever touches, so it reaches only projects you graduate from now on. And a Lab home that keeps noLog/TASKS.mdorLog/DECISIONS.md—~/.Labitself, by default — is never covered by either check, permanently. -
Bug fix: the 128 KB tracking-file block could silently skip on a large commit. v1.13.0 added a hard block for a tracking file staged over 128 KB, alongside its 64 KB warning tier. Both were fed by a shell pipe that exits at the first match — on a commit staging enough files, the writing side of that pipe was killed before it finished, and the failure was read as "no tracking file staged", so neither tier ran. The bigger the commit, the more likely it was to slip. Both tiers, and the new checks, now read their input without a pipe at all. No threshold and no message changed; the gate simply runs when it should. On an existing install:
update.shdelivers the fix.
Lab Zero v1.18.0 — plain-language wrap closer + constitution drift check
v1.18.0 — 2026-09-01
-
/wrapnow ends by telling you, in plain words, what just happened — and/brocan offer itself. A wrap used to end on a checklist: what was committed, what was reindexed, what the tracking files now say. Accurate, and hard to read when you're tired./wrapgains a final step: three or four short sentences, no headers, no bullets, no file paths or version numbers unless a number is the point — the same register/browrites in. Two guards are hard. The closer is written only after the checks above it have passed, so it can never announce an action that didn't fire; and every real caveat survives into it — dropping one to make the closer land cleanly is the single failure that step must not produce. It also may not invent scope: no "and next session we'll…". It never replaces the checklist, it follows it. Separately,/brois now model-invocable: your agent can reach for it on its own when an answer clearly didn't land, instead of waiting for you to type/bro. That also fixes a dead trigger — the skill has always advertised "or says the last answer was too dense", which was inoperative until now. The other ceremonies keep their manual-only flag; this is/broalone. On an existing install:update.shdelivers both, no config change needed. -
Your project can now tell you when its
AGENTS.mdhas drifted behind the engine.update.shdeliberately never touchesAGENTS.mdorCLAUDE.md— they're your constitution, and a whole-file refresh would destroy your own sections. Correct, but it leaves a gap: engine wording that lives inside those files can never reach you, so it goes stale silently and stays that way. Every commit now runs a short advisory check that reads a baseline shipped with the release and names any engine line no longer present in your constitution —[constitution] ⚠️ AGENTS.md carries engine prose that is out of date:, followed by each expected line. It is advisory and stays that way: it never edits a file, never reaches the network, and never blocks a commit — the shipped hook calls it so that even a broken copy of it cannot stop you committing. Two limits worth knowing: it runs on every commit, not only when you touch a constitution, because staleness is a property of a file nobody is editing; and it has no memory, so if you reworded a line on purpose it will keep naming that line — ignore it. If the baseline is missing or unreadable it prints nothing at all rather than guessing. On an existing install:update.shdelivers both the check and its baselines underscripts/. -
A project you graduate no longer gets a hardcoded list of its own skills. The
AGENTS.mdandCLAUDE.mdwritten into a new project used to name every ceremony inline. That list could only ever be right on the day it was stamped — and becauseupdate.shnever rewrites those two files, it could never be corrected afterwards. It's gone; both now point at the skills directory itself as the always-current list. This is the fix for a real failure:/broshipped in an earlier release and was left undocumented in four of five existing projects, with no mechanism that could have caught up. On an existing install: nothing changes — this is the project template, so it reaches projects you graduate from now on. Your ownAGENTS.mdis yours and is never overwritten; if it still names your skills one by one, that list is now yours to maintain or to delete. -
One caveat about the starter memories. This release also reworded one shipped starter memory — the one about what wrapping a session means — so it no longer reads as forbidding that new plain-language closer. It will not reach you if your Lab is already set up. Starter memories are copied into a fresh Lab home once, per filename, and an existing file is never overwritten, so any Lab that has already been seeded keeps the old wording permanently and has to edit it by hand. Graduated projects never receive the starter memories at all and are unaffected.
Lab Zero v1.17.0 — projects update their own engine
v1.17.0 — 2026-08-31
- Projects you graduate can now update their own engine. Until now a stamped project got the engine once, at stamp time, and never again: every drift meant a hand migration, and there was no way to even tell which engine version a project was on. Every project stamped from v1.17.0 ships its own
update.shplus an.agents/VERSIONstamp. Runbash update.sh --checkinside the project to see its engine version against the latest release plus what's new, andbash update.shto refresh the machinery —scripts/,tests/, the skills, the hooks,bootstrap.sh. Your project's own layer is never touched:Source/,AGENTS.md/CLAUDE.md,identity/,Log/,Sessions/,recall.config.jsonand.claude/settings.jsonare yours. (.claude/settings.jsonis excluded deliberately — it holds your project's absolute path from stamp time, and refreshing it would restore the raw placeholder and silently disable every hook.) It pulls the same published releases your Lab does, adds no git remote and writes no local tag, so your project's own release tags are left alone; setLAB_ZERO_UPSTREAMif you work from a fork. Projects stamped before v1.17.0 can install the updater with one line, run inside the project:git fetch -q https://github.com/cyb213/Lab-Zero.git refs/tags/v1.17.0 && git archive FETCH_HEAD template/update.sh | tar -x --strip-components=1— thenbash update.shbrings the rest, including the version stamp. Two limits worth knowing: updating adds and overwrites but never deletes, so a skill removed upstream leaves a stale copy behind (yourcheck-skills-sync.shpre-commit gate flags the skills case); and template content under your own directories —Log/plans/TEMPLATE.md, theSource/skeletons — never refreshes, because those directories belong to your project. Not included: re-pulling identity. Youridentity/IDENTITY.mdis a vendored copy and stays a hand copy. On an existing install:update.shdelivers the new template to your Lab, so projects you graduate from then on carry the updater; projects graduated earlier need the one-line install above.
Lab Zero v1.16.0 — the /bro ceremony
v1.16.0 — 2026-08-15
- New
/bro— ask for that last answer again, in plain words. When a reply lands too dense, too jargon-heavy or too long,/brore-explains the agent's own previous message — that is the whole job. It never answers a new question, never adds information that wasn't already there, and never reaches for a tool. Two guards are hard: every path, command, flag, number, version and name survives exactly as written (a "simpler" answer that rounds a version is a wrong answer), and every real caveat survives — dropping one to sound cleaner is the single failure it must not produce. It also flattens structure (headers gone, tables become plain sentences), replies in the language of the message it's re-explaining, and defaults to a casual voice unless yourIDENTITY.mddeclares a different register. If the agent now thinks the original answer was wrong, it says so instead of re-explaining a mistake more confidently. In Claude Code type/bro; on Codex there's no slash dispatcher, so just ask ("say that again, simpler"). Derived from the MIT-licensed bro-skill by Hermes Agent + Luka — rewritten for Lab Zero, with the upstream notice inside the skill file. On an existing install:update.shdelivers it, no config change needed; projects you graduated before this release don't get it retroactively.
Lab Zero v1.15.0 — plain-language responses
- Agents now answer you in plain, adaptive language. Both shipped constitutions — the root
AGENTS.mdand thetemplate/AGENTS.mdthat graduates into a new project — gain a short block: match the depth to the technical level you declared inIDENTITY.md, lead with the answer, explain or avoid jargon, keep sentences to one idea, and give one step per sentence when you have to act. The mechanics are borrowed from ASD-STE100 (Simplified Technical English) — short sentences, active voice, one name per thing — without its controlled dictionary. Two deliberate limits: it never trades exactness for simplicity (paths, commands, flags and versions stay verbatim, and a real caveat is never dropped to sound cleaner), and it doesn't touch code, tables, quoted output, or files the agent writes. Your own stated preferences still outrank it. This is guidance in the always-loaded constitution, not an enforced check. On an existing install:update.shrefreshestemplate/AGENTS.mdfor you, but your rootAGENTS.mdis yours — it's never overwritten, so copy the block across by hand if you want it there too.
Lab Zero v1.14.0 — lab-plan rightsizing
v1.14.0 — 2026-08-05
- The
/lab-planplanning ceremony now scales to the change instead of firing fixed. It used to trigger on a file-count ("more than ~2 files") and always run exactly 3 adversarial reviewer passes. Now it triggers on what the change touches — a fixed checklist (the shipped engine, a skill/template, a hook, recall, security, or a public release, plus genuinely wide multi-file features) — and treats 3 reviewers as a ceiling, not a floor: a change that trips the checklist still gets the full pass, but a small self-contained change can run fewer reviewers (or none), with the risk lens never the one dropped. If you don't use/lab-plan, nothing changes for you.
Lab Zero v1.13.0 — tracking-size block tier
- Oversized tracking files now block a commit (the 64 KB size warning gained a hard 128 KB tier). v1.12.0 added a warn-only notice when a staged tracking file (
Log/STATUS.md/TASKS.md/PLAN.md/DECISIONS.md) passed 64 KB — and said it never blocks a commit. This adds a second, blocking tier: a tracking file staged over 128 KB now fails the pre-commit hook (whole-file readability is load-bearing — a file that big has stopped being reliably readable in one pass). The 64 KB warn level (LAB_TRACKING_SIZE_WARN_KB) is unchanged; the new block level isLAB_TRACKING_SIZE_BLOCK_KB(default 128, and it can never be set below the warn level). To land an oversized tracking file anyway, bypass the hook withgit commit --no-verify. This only fires once a single tracking file crosses 128 KB, so if yours are a normal size nothing changes.