CLAUDE.md · diff
git:20261013.9e0aa9c to git:20261015.715d6b4
1 added, 1 removed. Audit B to B.
# Mycelium: Theory-Guided Agentic Product Development
- *Version 0.324.0 -- **The scope hold is switched on by the delivery cycle that needs it** (MINOR; 2026-10-13). Until now `hooks/scope-gate.sh` read the folders it holds the agent's writes to from `.claude/state/active-execution.json`, which nothing Mycelium ships wrote, so in a plugin install the hold was never on. Now a delivery cycle (an L4) names them on its own record when it commits to build (`in_scope_paths` in `.claude/diamonds/active.yml`; an empty list is "no hold"), the write is put to the person, and a commitment to build with nothing said is refused. While the cycle is open a write outside the folders is put to the person with the file named (it was refused outright before), and refused where nobody is asked; a write that changes or removes the folders is put to them too; the hold ends when the close is recorded. A shell command no hook can read could delete the record or take the folders off it unseen (found while building, by trying it): `bash-state-guard.sh` now keeps a copy of the diamonds file per command and puts the whole file back when the command changed what a cycle names, and tells the person (maintainer's ruling 2026-10-13); a change that came through the edit tools meanwhile is kept. REMOVED: the old state file is no longer read, and while one exists product writes are refused with what to do (his ruling, so that a hand-set hold is not dropped in silence); `out_of_scope_paths` and the `spec` nesting have no counterpart; the `diamond_id` label the two logs took from that file is gone. A cycle that committed before this release is not held, and session start names it. Pages, skill, schema, rules page and contract carry it. Shown by a replay of fourteen writes through the shipped hook (`tests/python/test_the_scope_hold_through_its_hook.py`), not by a real delivery cycle; the put-back is a check on drift, not a sandbox. Prior: 0.323.2 -- **The pages stop describing a scope check nothing switches on** (PATCH; 2026-10-13). `hooks/scope-gate.sh` holds the agent's writes to the paths named in `.claude/state/active-execution.json` and leaves at once when that file is absent. No skill, script or hook writes the file, so in a plugin install the check has never been on (a blind reader of the installed plugin, dogfood 2026-10-11). README.md stopped claiming the hold in 0.322.3. Five other pages went on describing it as working (`docs/ai-system-card.md`, `docs/context-surface.md`, `docs/nobody-used-it.md`, `PRIVACY.md`, `plugins/mycelium/hooks/README.md`), this repository's own `.claude/state/README.md` named `/diamond-progress` as the file's writer, and two refusals of `scripts/scope_check.py` told the reader to run that skill to "recreate" a file it never writes. Fixed, words only: each page says the check is off unless you write the file yourself; the system card lists it under known limitations; the maintainer's page no longer mentions it (his wording, chosen 2026-10-13); the helper's messages say repair or delete the file. The gate itself is unchanged: a state file written by hand is still held to. The mechanism that would switch the check on (the folders kept on the delivery cycle's own record) has passed a replay in a scratch copy and is its own delivery work; the maintainer chose to make the pages true first. `tests/python/test_the_pages_say_the_scope_check_is_not_switched_on.py` (14 cases; 10 fail on the 0.323.1 pages) holds pages and plugin together both ways: it fails if a page drops the admission while nothing shipped writes the file, and fails the other way the day something does. Prior: 0.323.1 -- **Mycelium's own tests pass its own commit scan, and the printed hook lines no longer lock out a machine without the scanner** (PATCH; 2026-10-13). 0.323.0 added a scan of what is committed and pushed and was never run over Mycelium's own tree. Run the day after (dogfood 2026-10-13): gitleaks flags eight lines in four test files, made-up values in the shape of real credentials, so the scan refused any commit that touched them; the 0.323.0 release commit added two of those lines and passed only because the session that made it still ran the older hooks. Second fault: for a clone that already has a pre-commit hook, `scripts/install_git_secret_hook.py` printed a line to add to it, and that line exited 1 when gitleaks was not installed, refusing every commit there, where the hook the script writes itself says the commit was not scanned and lets it through. Fixed: the written hook and the printed lines are one block (`SCAN`); the test values are put together from two halves at run time, or are plain text where the value was incidental (K6 in `tests/bash/test_hooks_adversarial.sh` is renamed for what it checks: a write the gate cannot read is refused). No ignore file, scanner configuration or allow comment was added. New: `tests/python/test_no_tracked_file_trips_the_secret_scanner.py` stages every tracked file in a throwaway repository and asks the shipped `commit_scan.scan_staged` about it (red on the eight lines before the fix; skipped where gitleaks is not installed, which includes CI; the fallback list matches one tracked line, the key a holdout eval scenario hands the agent on purpose, left as it is); three tests run the printed lines with no scanner, with a scanner that finds nothing and with one that finds something. Each edited test was shown to still go red when the behaviour it checks is switched off. Prior: 0.323.0 -- **Secrets are stopped at the commit and the push, by an established scanner** (MINOR; 2026-10-12). Until now Mycelium looked for secrets when the agent WROTE a file, with a short list of its own. Replayed 2026-10-12: an unquoted `KEY=value` passed, an env file was treated like source code, and nothing looked at what was staged. The maintainer: "Don't let passwords into the repo"; "using established scanners are the way to go"; and, asked each in turn, "Stop refusing writes", "Fall back, and say so", "Agent must ask you first", then to the whole design said back, "Build it now". NOW (`scripts/commit_scan.py`): before the agent's `git commit`, what the commit would take is scanned (the index; with `-a` or a named path, tracked files as on disk); after any shell command, commits the command itself made are scanned, read from HEAD's reflog (`bash_state_guard.py`), and a finding is said and the commit left alone; before the agent's `git push`, every commit on a local branch that is on no remote is scanned. A finding refuses the commit or the push and names file and line, never the value. The scanner is gitleaks when installed; without it Mycelium's own list (`scripts/_secret_patterns.sh`, run by `_secret_grep.sh`) runs and the person is told once a session it is the weaker check. A scan that cannot run refuses. REMOVED IN THE SAME RELEASE: the scan of a file write in `hooks/gate.sh`. The agent may write a key into a file; it may not commit or push one. KEPT: a key typed into a shell command is refused. GUARDED: `.gitleaksignore` and `.gitleaks.toml` join `GUARD_STATE_REL`, and a write adding a `gitleaks:allow` comment asks the person. OFFERED, NEVER UNASKED: `/mycelium:setup` offers `scripts/install_git_secret_hook.py`, a pre-commit hook for commits made by hand; it never overwrites one that exists. README.md carries the maintainer's chosen sentence; PRIVACY.md, the system card, the hooks reference, the guardrails and the operating contract say the same. NOT SHOWN: any of it on Linux or Windows, or in a live session; a folder held in a shell variable; a `gitleaks:allow` added by a shell command. The scan follows the folder a command names (a `cd` before the commit, `git -C <folder>`), so a commit made in another repository is scanned there. `tests/python/test_secrets_are_stopped_at_the_commit.py`: 64 cases; `test_the_secret_scan_covers_dot_claude.py` is retired with the behaviour it pinned. Prior: 0.322.7 -- **The pages say what the build gate does not see** (PATCH; 2026-10-12). README.md said "the agent cannot create a brand new source file" and that building waits "new files and edits alike". The build gate judges a write it can read (the edit tools and plain shell writes); a command the agent runs that writes the files for it gives the gate nothing to read. Replayed on 0.322.3 by a blind read and again on 0.322.6, in a project where a plain redirect to a new source file is refused: a scaffolder, `npm init`, `cargo new`, `git clone`, `curl -o`, a script that writes, `patch` and `git apply` each pass with nothing said. NOW: no gate changes. README.md says the limit beside the claim, in the maintainer's chosen wording ("That covers the files the agent writes itself. A command it runs that writes them for it, a scaffolder or a clone, still gets through."), and `docs/ai-system-card.md` lists it under known limitations with the eight commands named. WHY NOT THE FIX: a before-and-after comparison through git held in three desk tests and in a scale benchmark on one Mac; the maintainer was not sure of it on Linux and Windows, and parked it until real users say which platforms they are on. NOT CHANGED: `docs/get-started.md` and the plugin description carry the same claim in softer words and were left as they are by the maintainer's choice. `tests/python/test_the_pages_say_what_the_build_gate_does_not_see.py` holds pages and gate together both ways: it fails when a page stops saying the limit, and it fails when the gate starts refusing one of the eight, with the instruction to take the sentence out. Prior: 0.322.6 -- **A Mycelium switch in a Claude Code settings file is the person's to set** (PATCH; 2026-10-12). Three environment variables loosen a Mycelium stop (`MYCELIUM_GUARD_STATE_EDIT`, `MYCELIUM_NEXT_ACTION_CHECK`, `MYCELIUM_TODAY`), and a hook cannot tell who set a variable. Claude Code takes variables from the `env` block of a settings file and re-reads the file mid-session, and two more keys there end every hook (`disableAllHooks`, and `enabledPlugins` with the plugin set to false). No Mycelium gate looked at a write to those files: replayed 2026-10-12 on 0.322.1, a tool call that put the override into `.claude/settings.local.json` drew no decision, while a write to `discovery-skip-ack` in the same replay was asked about. NOW: new `scripts/settings_switches.py` reads the Mycelium switches in a settings text (every `MYCELIUM_*` variable, `CLAUDE_PROJECT_DIR`, `CLAUDE_PLUGIN_ROOT`, and the two keys). `guard-state-gate.sh` works out what a file tool would leave in `.claude/settings.json`, `.claude/settings.local.json` or `~/.claude/settings.json`; a new switch, or a changed value, asks the person and is refused where nobody is asked; an edit that sets none is not asked about. `bash-state-guard.sh` notes the switches before each shell command (names and values, never the file) and afterwards takes a new one out again, keeping the rest of the file, the home-folder file included (maintainer: "Undo that line, tell me"); the plugin switched off in `enabledPlugins` is reported and left, because Claude Code's own plugin commands write that key. The person's override is read as it was BEFORE the command, so an override the command wrote cannot switch off its own undoing. COST: setting any `MYCELIUM_*` variable through the agent now costs one answer; a switch the person adds by hand while the agent's shell command runs is taken out with the rest. NOT SHOWN: any of it in a live session or in any permission mode; that hook commands receive the `env` block is Claude Code's documentation. NOT COVERED: variables that change how a shell starts (`BASH_ENV`, `PATH`), an edit through a symlink not named `settings.json`, Cursor's and Codex's own settings, managed and command-line settings. `tests/python/test_a_settings_file_switch_asks_the_person.py`: 50 cases, 30 of them fail on the 0.322.5 code. Prior: 0.322.5 -- **A diamonds file that cannot be read does not open the gates** (PATCH; 2026-10-12). `.claude/diamonds/active.yml` says what may be built. The build gate decided whether discovery was engaged by reading it behind handlers that caught `ValueError`, and a YAML error is not one: a file that did not parse crashed the check, the crash's exit status read as "not engaged", and an edit of product code was allowed with nothing said. Replayed on 0.322.4 in a project with diamonds and no written purpose: refused while the file was readable; allowed once it held git conflict markers, was invalid YAML, was a list, or was empty. With a purpose written the edit was refused in every state, for the wrong stated reason. A merge conflict is enough to get there. NOW: `_hook_input.py --discovery-state` answers 4 for a diamonds file that is there and cannot be read, and `--diamonds-unreadable-why` says why; `discovery-gate.sh` and `exposure-gate.sh` refuse with that reason, `brownfield-gate.sh` stands aside, and `preflight.sh` tells the agent at the prompt. An emptied file counts only where `diamond-rulings.json` shows the project had diamonds. A `purpose.yml` that does not parse no longer crashes the check. ALSO: `vercel --prod` now reaches the release checker; the hook's word filter, which runs before the checker, had no word for it, so a production deploy by that command was never judged (found while replaying the release gate for this fix). HOW IT CAME UP: an unsolicited one-line email named `_hook_input.py:530`; the line is real, the email's description of it (a hidden "connection drop") is not, since the file has no network code. NOT SHOWN: whether the agent can make the diamonds file unreadable through its own tools (shell writes to it are refused; the scale lock judges Edit and Write, and its handling of an unparseable result was not replayed); anything on Cursor or Codex. `tests/python/test_an_unreadable_diamonds_file_does_not_open_the_gates.py`: 52 cases, 22 of them fail on the 0.322.4 code. Prior: 0.322.4 -- **A hook's Python imports nothing from the project** (PATCH; 2026-10-12). A hole in every released version, found by listing every place a hook starts an interpreter after a blind reader showed 0.322.3's "a hook never runs a script from the project" was false at one site. THE HOLE: hooks run inline Python (`python3 -c`, `python3 -`) with the project as the working directory, and Python puts that directory first on its import path, so `import json` loaded `./json.py` when the project had one. Replayed on 0.322.3 with the plugin root SET, as Claude Code runs the hooks: 19 of the 56 registered hook entries imported a planted `json.py`, `yaml.py` or `re.py` (preflight on every prompt, the gate on every write, the turn-end hook, session start). A repository could have its own code run by the hooks with nothing in its settings to show for it. Claude Code's folder-trust question comes first, and a trusted repository could already run code through its own hook settings; this path was invisible there. THE FIX: `scripts/_hook_prelude.sh`, which every hook sources on line 2, exports `PYTHONSAFEPATH=1` (Python 3.11 and later) and defines `python3`, `python` and `_mycelium_py`, which hand inline code to the new `scripts/_safe_c.py`; a Python file gets its own folder on the path in place of the working directory, on every version. Call sites are unchanged, except four that start an interpreter by path or variable (one in `_python.sh`, one in `preflight.sh`, two in `_hook_fire_log.sh`). ALSO: the two sites a round 3 reader and the same audit found (`session-start.sh`, `stop-check.sh`) that put the project's `scripts` folder on the import path when `CLAUDE_PLUGIN_ROOT` is unset now use the hook's own folder; on 0.322.3 a planted `scripts/scale_locks.py` ran at session start. NOT SHOWN: that an honest project's own `types.py` or `json.py` changes what any gate decides; tested on eight gates and the build gate's two decisions, every decision unchanged, so the first version of this note's author claim to the maintainer that such a file "breaks honest projects" is withdrawn. Not run on Cursor, Codex or a Python older than the one on this machine and in CI; the launcher path is tested with `PYTHONSAFEPATH` unset. `tests/python/test_hooks_import_nothing_from_the_project.py`: 76 cases, 26 of them fail on the 0.322.3 hooks (the launcher is a new file, so its own tests pass beside the old hooks too); four of the 76 run the launcher in-process, added after CI's per-file coverage floor read it as untested. Prior: 0.322.3 -- **What the second blind read found: the secret scan covers `.claude/`, hooks run only their own scripts, a session start counts once, the opencode scaffold leaves your skills alone** (PATCH; 2026-10-12). Three new readers compared the pages of 0.322.2 with its code; none was clean, and after checking they had 15, 9 and 10 counted findings, six of them defects in behaviour and five of them sentences that 0.321.1 and 0.322.2 had put in wrongly. (1) THE SECRET SCAN COVERS `.claude/` (maintainer: "Scan .claude/ too"): `gate.sh` skipped every target under `.claude/`, so a key written into a canvas file, the decision log or memory, all committed, was never scanned; now only `.claude/state/` is skipped. A file outside the project is still not scanned. The scan has no override, so a note that quotes something key-shaped must be reworded. (2) A HOOK NEVER RUNS A SCRIPT FROM THE PROJECT: with no `CLAUDE_PLUGIN_ROOT` (Cursor, Codex) a hook fell back to `$PROJECT_DIR/.claude/scripts/` and `.claude/hooks/`, the old copied-in layout, 41 lines in 12 files, so a repository carrying a file by the right name had it run; a test that plants one shows `gate.sh` ran a planted `preflight.sh` and `session-start.sh` ran two planted checks on 0.322.2. Helpers now resolve under `_MYCELIUM_ROOT`, the folder above the running hook. Not run on Cursor or Codex. (3) ONE SESSION START COUNTS ONCE: `session-start.sh` runs twice per start on Claude Code (`--fast`, `--async`) and both passes incremented each open `*.count.json`, so a ten-session test reported done after five; the background pass now only reads. (4) THE OPENCODE SCAFFOLD LEAVES WHAT IS NOT ITS OWN (maintainer: "Never overwrite, never unasked"): `provision-skills.sh` copied over an existing `.claude/skills/` and rewrote paths in every file there; it now marks the folders it copies, replaces only marked ones, skips and names the rest, and rewrites only what it copied. The starter `opencode.json` asks before any skill that is not Mycelium's, and `/mycelium:setup` writes no scaffold in a non-interactive run unless opencode support was asked for by name. (5) TEXT: the end-of-turn count no longer says "this session" for every row the log holds; the failed-command prompt no longer cites a `CLAUDE.md` section the plugin does not ship; `PRIVACY.md` corrected where 0.322.2 was wrong (opencode "two things only", "nothing leaves your machine", what `diamond-rulings.json` stores, "adds one") and extended (scan scope, `conditional-snoozes-said`, the shell guard's index, `nudge-seen.jsonl` never trimmed, `install-runtime-hooks.sh` creating a state folder, the file listing at session start, `/mycelium:migrate-from-legacy` downloading); the system card lists what the release gate reads as a release and drops a `.claude/.gitignore` it never wrote; `README.md` and `docs/get-started.md` carry three sentences in the maintainer's wording, and the README sentence about the scope hold is removed because nothing the plugin ships switches that hold on (maintainer: "Make it real"; it returns when the hold is wired). Tests: `test_the_secret_scan_covers_dot_claude.py` (6), `test_hooks_run_only_their_own_scripts.py` (7), `test_a_session_start_counts_once.py` (5), `test_opencode_scaffold_leaves_your_skills_alone.py` (8). Prior: 0.322.2 -- **The pages a newcomer reads say what the plugin does; a scale-lock override is kept in git** (PATCH; 2026-10-12). Text corrections, plus one fix found while writing them. A blind read of 0.321.0 by three readers compared `README.md`, `PRIVACY.md`, `docs/get-started.md` and `docs/ai-system-card.md` with the code; 0.321.1 answered its two safeguard findings and three README sentences, and this release answers the rest, each checked again against 0.322.1. `PRIVACY.md`: opencode does not run the hooks (it runs a two-check plugin); the hooks read every tool call and the whole text of every shell command, and a hook reads the session transcript at the end of every turn; session start increments open `*.count.json` counters, which are committed files, and reads git `user.name`, `user.email` and the origin address in memory; `/mycelium:setup` probes for opencode and can write `opencode.json` and `.opencode/` at the project root; twelve state files that had no line are listed, among them `session-checks.json` (the full text of a session's reminders); `exposure-uses.jsonl` is named as the one log that keeps part of a command by default; `MYCELIUM_CROSS_REPO_WATCH` reads commit bodies, not only subjects; and "collects nothing" now says nothing leaves the machine while logs are kept locally. `docs/environment.md` said "every variable in one place" and named 9 of the 28 `MYCELIUM_*` names the plugin tree uses; it now names all 28, and says which three loosen a stop (`MYCELIUM_GUARD_STATE_EDIT`, `MYCELIUM_NEXT_ACTION_CHECK`, `MYCELIUM_TODAY`). `docs/ai-system-card.md`: the agent's rules arrive through the session-start hook, not a `CLAUDE.md`; advisories mute after seven days, not seven sessions; `gate.sh` logs two of its five refusals in its own log and all five in the denial ledger; the denial ledger is trimmed; the secret scan reads shell commands as well as writes. `README.md` and `docs/get-started.md`: two sentences in the maintainer's wording (a repo is asked about existing code only from a dozen source files; the first run writes four files, not two). New `tests/python/test_newcomer_pages_name_what_runs.py` fails when a `MYCELIUM_*` name or a `.claude/state/` file the plugin uses has no line on its page (3 of its 4 tests fail on the 0.322.1 pages); it checks that a name is present, not that what is said about it is true. THE FIX: `scale-lock-ack`, the person's own override of a scale lock, was the one decision file the state folder's ignore file did not keep in git, so a fresh clone had the lock closed again with no record (maintainer, shown it: "not intentional to my knowledge. Apply best practices."). `scripts/state-gitignore.txt` keeps it now. An ignore file that exists is never rewritten, so `session-start.sh` says `DECISION FILE NOT IN GIT` when any of the five decision files exists and is ignored by that folder's own ignore file, with the line to add (`_state_dir.py --ignored-decisions`, `git check-ignore`, read-only); a rule from elsewhere, such as a root `.gitignore` that leaves out `.claude/`, is the person's choice and is not reported. `tests/python/test_decision_files_stay_in_git.py` (13). Prior: 0.322.1 -- **A gate that cannot run refuses the call, in a project that uses Mycelium; session start keeps what a person wrote** (PATCH; 2026-10-12). Claude Code lets a tool call through when a hook cannot start, times out or exits with an unexpected status, so every Mycelium gate let the write through in those cases. The nine gates that can refuse now carry `"onFailure": "block"` (Claude Code 2.1.295 or later), behind a check in the command itself that leaves at once in a project without `.claude/canvas/` or `.claude/diamonds/`, so a hook that cannot start refuses only where Mycelium is in use. A refusal that could not be printed because python3 cannot run is now a refusal too. Session start no longer overwrites hand-written content inside a diamond's stored closing path: it leaves that block alone and says where to move the content. On Windows without Git Bash the commands cannot run and writes are refused in every project. Prior: 0.322.0 -- **A project that deploys is asked whether something is already live** (MINOR; 2026-10-11). The release gate judges a deploy the agent runs, against exposure records, so a product somebody put live by hand sat outside the Security and Privacy checks and nothing named it. Now, when a project uses Mycelium, its repository shows it deploys (a host's config file, a workflow that deploys) and no diamond records who it reaches, one line at session start asks whether something is already in front of real people and offers to record it; `/mycelium:adopt` asks the same when Mycelium is brought into existing code. The sign shows the project can deploy, not that it is live, so it is a question. It stops once answered, and nothing about it is read by any gate. Prior: 0.321.1 -- **Two stops that could be walked around** (PATCH; 2026-10-11). Both found by a blind read of 0.321.0. (1) A shell write through a variable reached a file that switches a stop off, and nobody was asked: the hook that asks can only read a write target it can see. The files that switch a stop off are now compared before and after every shell command, also one that fails, and a change the person was not asked about is put back and reported to them. (2) The build gate counted an edit as building for the Edit tools only; a whole-file write over existing product code, a notebook edit and a shell edit passed. A write to an existing product file is now judged as an edit whatever tool makes it. Three README sentences the same read found untrue are corrected in the maintainer's wording (nothing is held before `/mycelium:start`; the agent can write an off-switch file only if you agree; not everything else is a warning). Nothing here adds a way past a stop. Prior: 0.321.0 -- **The harms check is named at release, as advice that never blocks** (MINOR; 2026-10-11). `/mycelium:harms-check` asks who a product could harm when it works as designed, and nothing that runs named it: in 175 end-to-end runs it was mentioned in 1, against 33 for the privacy check, whose record the release gate requires. Now, when a current exposure record has no harms check recorded on it, the release path says so in one advisory line (as context on an allowed release, in `scale_locks.py --exposure-state` and `--exposures`, and in the gate's refusal beside the required checks), and the verdict is recorded on the exposure as `harms_check: {on, verdict, note}`. No verdict, missing or Happier-negative, changes what is allowed or refused. Prior: 0.320.0 -- **A leaf bakeoff is decided by its tests, not by a gap in ICE scores** (MINOR; 2026-10-11). Until now a 20% gap in ICE totals decided whether competing ideas for one opportunity were compared and which one won; no source has that rule. Leaves are now compared whenever two or more each have an untested riskiest assumption, the assumption-test verdicts decide, and the ICE total only orders which assumption is tested first. The `bakeoff_delta` threshold is retired with its calibration rule (a canvas that still carries it validates and gets one WARN). The Noise Check in `/mycelium:ice-score` no longer gives a "1 point" number it had no source for. This changes which leaves an agent compares and which one it advances. Prior: 0.319.2 -- **The work-recording check counts releases from version tags** (PATCH; 2026-10-11). `check_cycle_recording.py` counted minor releases by parsing commit subjects, in repositories that carry a version tag per release. It now reads the release repository's version tags (`v1.4.0` or `1.4.0`) when it has any, and commit subjects only when it has none; the output says which it read. A repository with tags and no new minor tag since the last cycle is a measured zero, not "could not measure". `--release-pattern` still forces the subject scan. Prior: 0.319.1 -- **The suite cannot write into the repository of whoever runs it; the secret scan refuses when it cannot run** (PATCH; 2026-10-11). Run from a git worktree, the pre-push hook's tests acted on the repository being pushed: git exports `GIT_DIR` to hooks there, so fixture `git init`, `config` and `commit` calls wrote `core.bare = true`, a dummy author and fourteen commits into the real repository. Every place that runs the suite now clears the variables that redirect git, fixture repositories are checked before use, and a test fails any bare `git init` in a test file. Separately, the secret scan treated a grep that could not run as "no match"; it now refuses the write and says the scan failed. The scan has no override, by design. Also: `scripts/gates.sh` wrote its verdict through `tee /dev/stderr`, which on Linux empties the log the script is redirected to; it is now two plain writes. If you installed the pre-push hook, copy it again. Prior: 0.319.0 -- **ICE as Gilad defines it: multiplied, with his Confidence Meter, and no threshold on the total** (MINOR; 2026-10-11). The literature has two versions of ICE and Mycelium had matched neither: it averaged, as Ellis does, while describing Gilad's meter with values that are in no version of it, and kept a threshold of 100 on the total that no source has. On the founder's choice `/mycelium:ice-score` now computes Impact x Confidence x Ease, each 0-10, with Impact against a named metric, Ease as the effort to build in full, and Confidence summed from evidence with the Confidence Meter's own weights and caps. The total is a hint for comparing ideas; a low rank parks a leaf and never kills it; `ice_advance` is retired. `check_ice_aggregate.py` turned with the rule and still never rewrites a canvas: run it once with `--write-baseline` after upgrading. Rankings change; old scores are left as they are. Prior: 0.318.4 -- **The README, the get-started page and the menu say what the brief switches on** (PATCH; 2026-10-11). Three README passages that said nothing is held after the four questions are rewritten in the founder's words; get-started no longer says "Building is open whichever you pick"; and the menu after the brief follows the framework's own rules for choices: the hold is said first, one option is always recommended, three are listed, "build a prototype to learn" is one of them, and the friction-log line invokes `/mycelium:friction-log`. No behaviour changes. Prior: 0.318.3 -- **Two safeguards that did not hold** (PATCH; 2026-10-11). Removing `.claude/canvas` and `.claude/diamonds`, which switches every hook off, is now judged by `guard-state-gate.sh` as 0.318.0 said it was: the hook's cheap exit had let the removal through before the helper saw it, in every permission mode. The secret scan in `gate.sh` uses POSIX classes: under the BSD grep on macOS its bracket expressions read `\s` as the letter s and `\x27` as x, 2 and 7, so a credential was caught or passed by its letters. A database address with no password is no longer refused as a secret. Thirty-five new tests, all but one run through the hooks themselves; sixteen of them fail on 0.318.2 under the grep macOS ships. Prior: 0.318.2 -- **Two notes and a welcome say what the code does** (PATCH; 2026-10-11). The ICE note and the confidence-thresholds comment no longer say Gilad's confidence penalty is preserved: nothing computes a weighting, the average carries no penalty, and the note now says what stands in its place and tells the agent to report Confidence beside every score. `/gist-plan` scores Confidence 1-10 like `/ice-score`. The start welcome says, before the first question, that building the product waits for a delivery diamond once the brief exists, and how to lift that. No behaviour changes. Prior: 0.318.1 -- **Four false readings from one dogfood session** (PATCH; 2026-10-10). A premortem's task mention is no longer a closing input; a `{id, ref}` pointer is no longer a duplicate id; a variable before `..` no longer normalises into a project path; and the diamonds-file guard no longer refuses a read that writes elsewhere through a variable. Prior: 0.318.0 -- **Nothing outside a Mycelium project; inside one, logs listed, trimmed, kept out of git, and holding no commands** (MINOR; 2026-10-10). From Anthropic's plugin directory review of v0.317.4 and the founder's rulings on it: in a project with no .claude/canvas or .claude/diamonds every hook exits at once, with no gate, output or log (a fresh repo is no longer gated before /mycelium:start); in a Mycelium project the reflexion log keeps the time, exit code and program name, never a failed command or its output unless the user opts in (masked), activity logs keep 90 days (MYCELIUM_LOG_RETENTION_DAYS), and every hook writes `.claude/state`'s ignore file on exit when it is missing; the release gate allows a project with no diamonds file before it needs PyYAML; PRIVACY.md lists every log, what a line holds and how long it is kept. Prior: 0.317.5 -- **A scored instrument is not "no expiry" either** (PATCH; 2026-10-08). check_instrument_contract skips scored as well as void instruments in its expiry step. Prior: 0.317.4 -- **A void instrument is not a problem** (PATCH; 2026-10-08). check_instrument_contract no longer reports void instruments as NO EXPIRY or as undersized/oversized. Prior: 0.317.3 -- **A review marker under `what` no longer supersedes the purpose** (PATCH; 2026-10-08). The purpose intent hash also drops the framework's reviewed markers (handles_checked, reply_not_owed, stale_prose_reviewed, checked_skills, checked_against); hashes stamped under v0.141.0 stay accepted. Prior: 0.317.2 -- **define-done: at the learning scales, "what changes" names the decision** (PATCH; 2026-10-08). Step 1 gains an L0-L3 branch (the change is what the owner can now decide, so the outcome names the decision the answer unlocks) and a rule that a problem is named in words, never by an id alone. Prior: 0.317.1 -- **`jtbd-map` uses Ulwick's opportunity score** (PATCH; 2026-10-08). The 2026-09-20 formula correction missed this second copy; step 5 now points to user-needs-map's definition. Prior: 0.317.0 -- **Other people's language is read for meaning, not for words** (MINOR; 2026-10-08). From a consumer project: skills that read interviews, posts, reviews or tickets as evidence matched on words, so they under-counted by construction and read a search's silence as an absence (dogfood measurement: a phrase filter caught 2 of 25 posts found by reading for meaning). New engine/reading-for-meaning.md, pointers in ten skills at the step where they read language, and validator Check 56 for the wiring. Prior: 0.316.3, in which preflight no longer waits forever when an agent runs it.**Preflight no longer waits forever when an agent runs it** (PATCH; 2026-10-07). A shell-tool command containing a heredoc gets a stdin socket that never reaches EOF, and preflight read its payload with $(cat), so an agent re-running it as gate.sh instructs could hang (35 minutes observed). The read is now bounded to 3 s, reproduced and tested both ways. Prior: 0.316.2, in which the plugin's own README says what it connects to.**The plugin's own README says what it connects to** (PATCH; 2026-10-07). The plugin README linked to a PRIVACY.md that installed users do not get; it now lists the one automatic call (ci-signal to GitHub via gh) and every user-started network action, and PRIVACY.md no longer claims Mycelium reads no credential while metrics-pull uses the credentials you configured. Prior: 0.316.1, in which skills stop pointing at things an installed plugin does not have.**Skills stop pointing at things an installed plugin does not have** (PATCH; 2026-10-07). From a /doctor prompt-audit run, each finding checked against the source: 38 skill pointers to CLAUDE.md sections now name the operating contract; a 22-skill preflight line lost stale line numbers and a dogfood-only reference; diamond-assess counts gates at run time (it said 13, the engine has 15); interview no longer recommends npx degit or phase moves; three links that left the plugin folder are GitHub URLs. Prior: 0.316.0 a refusal another extension overrules is said.**A refusal another extension overrules is said** (MINOR; 2026-10-07). Claude Code 2.1.287 shipped Mods, and a mod can approve a call a plugin PreToolUse hook refused, which every Mycelium gate is; the fire logs still said the gate held. Each refusal now writes its tool_use_id to a denial ledger, and a new PostToolUse hook (gate-override-check.sh) tells the person and the agent when a refused call ran anyway. Proven against a real test mod under claude -p. Prior: 0.315.0 a scale-lock block says what was missing.**A scale-lock block says what was missing** (MINOR; 2026-10-05). The scale-lock gate logged every refusal as `blocked` and nothing else: 110 blocks across 62 E2E runs, none saying whether a missing upstream record (the entry lock) or a diamond's own decision gates stopped the builder. Each refusal now carries its kinds (`entry_lock`, `decision_gates`, `rewritten_decision`, ...) as the block log's detail, so where builders are stopped, and by what, can be measured. Prior: 0.314.1 correction to the v0.314.0 notes.**Correction to the v0.314.0 notes** (PATCH; 2026-10-05). v0.314.0 cited two dogfood `scenario:` keys as leaves following ost-builder step 6; both are `dogfood_result.scenario`, eval-fixture paths unrelated to the scenario link. The changelog entry and the check's docstring are corrected; the defect and its fix stand, with no behaviour change. Prior: 0.314.0 a scenario names the opportunities it illustrates.**A scenario names the opportunities it illustrates** (MINOR; 2026-10-05). ost-builder told each solution to name its scenarios and asked whether every leaf opportunity has one, but no schema declared either link and nothing read one. Scenarios now carry the link in `addresses_opportunities` (declared); a solution's scenarios are derived from its opportunity; validate_canvas reports dangling ids and counts open opportunities with solutions that no scenario names. Prior: 0.313.1 a parked diamond still holds its slot.**A parked diamond still holds its slot** (PATCH; 2026-10-05). 0.312.1 taught the closing path about parks, but the slot checks used is_open, which leaves parked out: a parked L3 read as "no L3 works it", so the next item offered a second L3 on the same target, and one-L2-per-outcome, one-L3-per-target and the re-target rule all ignored a park. They now read holds_slot (open or parked). Prior: 0.313.0 a choice is written when it is made.**A choice is written when it is made** (MINOR; 2026-10-05). An L2's target and an L3's front runner are choices that a gated decision later records; when the decision was held for evidence, the skills let the choice be withheld as if it were the decision, so the next item asked every session for a comparison already made. ost-builder and diamond-progress now say the choice is written when made, and the next item names a ruled L2 whose choice was never written. Prior: 0.312.3 the icon's corners are transparent.**The icon's corners are transparent** (PATCH; 2026-10-04). The plugin icon had opaque white outside its rounded square, which showed as white corners on any dark surface; the corners are now transparent and the curved edge keeps its anti-aliasing. Prior: 0.312.2 a closed diamond is not derived either.**A closed diamond is not derived either** (PATCH; 2026-10-04). 0.312.1 taught the closing-path controller about parked diamonds only; a diamond archived, completed, killed or retargeted in place was still given a closing path, and a verdict landing on it became the session's next item, "run /mycelium:diamond-progress" on a stopped diamond. The controller and the next-item picker now read the same closed set scale_locks uses. Prior: 0.312.1 a parked diamond is not an unnoticed gap.**A parked diamond is not an unnoticed gap** (PATCH; 2026-10-04). The closing-path controller reported a parked diamond as "NOTHING ON RECORD moves a pending gate", so session start kept flagging a deliberate pause; it now prints when it was parked and how many resume conditions it has, and derives nothing for it. Prior: 0.312.0 a quieted advisory speaks again when its count rises.**A quieted advisory speaks again when its count rises** (MINOR; 2026-10-04). The advisory ledger records the count an advisory was muted or ruled at, and shows it once, with its own text, when the count rises past that; an advisory its own check forbids clearing mutes without asking for a ruling. Prior: 0.311.1 a private way to report a vulnerability.**A private way to report a vulnerability** (PATCH; 2026-10-04). SECURITY.md names the route (GitHub private vulnerability reporting, now on) and what a solo maintainer can promise: acknowledgement within 7 days, serious issues fixed or mitigated within 30, latest release only; the system card's contact section points to it. Prior: 0.311.0 a framework turn's Next: line cites its trigger.**A framework turn's Next: line cites its trigger** (MINOR; 2026-10-03). next-action-check.sh now blocks, once, a Next: line with no (per: <source>), giving contract rule 4 a mechanism after two audits measured it at 3 sessions in 12 as prose; and it now checks turns started by a /mycelium: slash command the person typed, which it never saw before. Prior: 0.310.20 context-surface.md is stamped against the hooks too.**context-surface.md is stamped against the hooks too** (PATCH; 2026-10-03). The hook-digest check that keeps the system card honest now also holds docs/context-surface.md, the second document that describes the hook layer; it missed the contract's move in 0.310.16 because nothing stamped it. Reading it against the hooks found four blocking or asking hooks it did not name, and hooks/README.md, the full table, missing four. Prior: 0.310.19 the docs name the contract's real injector and drop a stopped pilot.**The docs name the contract's real injector and drop a stopped pilot** (PATCH; 2026-10-03). docs/context-surface.md said session-start.sh injects the operating contract; since 0.310.16 contract-part.sh does, in four parts. The system card named the Juniors.dev pilot, stopped on 2026-08-14, as the next test, and gave the fifth audit as the last. Prior: 0.310.18 hook hygiene from the plugins-reference review.**Hook hygiene from the plugins-reference review** (PATCH; 2026-10-03). Nine handlers get explicit timeouts, shell-safety-guard its own status line, ping is kept from model invocation, and the carried-over reflexion warning, unreachable after session-start.sh's exit since v0.64.0, finally reaches the session. Prior: 0.310.17 the tests follow the contract to its new home.**The tests follow the contract to its new home** (PATCH; 2026-10-03). Five tests and Check 47's fixtures assumed session-start.sh carried the contract; they now check the contract-part.sh handlers and the cap. Prior: 0.310.16 the operating contract reaches the model whole.**The operating contract reaches the model whole** (PATCH; plugins-reference review 2026-10-03, founder go). Claude Code caps a hook's additionalContext at 10,000 characters and shows a 2,000-character preview of anything longer; the contract (about 22,000) rode in one string, so sessions got its first section. It now arrives in four parts that each fit, with the real plugin path in place of ${CLAUDE_PLUGIN_ROOT}. Prior: 0.310.15 Mycelium has an icon.**Mycelium has an icon** (PATCH; founder approved 2026-10-03). A square PNG at .claude-plugin/icon.png, named by plugin.json's icon field, for the Claude directory listing. Prior: 0.310.14 update instructions that work.**Update instructions that work** (PATCH; plugins-reference review, 2026-10-03). The docs said plugin auto-update is on by default and gave a command that only refreshes the catalog; for this marketplace auto-update is off by default. Prior: 0.310.13 what Mycelium runs and connects to, stated truthfully.**What Mycelium runs and connects to, stated truthfully** (PATCH; Claude directory review, 2026-10-03). The link checker no longer reads a GitHub token from the environment; PRIVACY.md, the system card, hooks/README.md, environment.md and the plugin README now say what the code does. Prior: 0.310.12 hook commands quote the plugin path.**Hook commands quote the plugin path** (PATCH; `claude plugin validate` warnings, 2026-10-03). Every hook command in the Claude Code, Codex and Cursor manifests used its plugin path without quotes, so an install path with a space split the command; all are quoted now and validate passes with no warnings. Prior: 0.310.11 leaf-lifecycle.md names its steps by decision, not by retired phase.**leaf-lifecycle.md names its steps by decision, not by retired phase** (PATCH; docs north-star reference cleanup, 2026-10-03). Its nine step headings and the L4 note used Discover/Define/Develop/Deliver, retired in v0.306.0; each now names the decision it sits beside. Prior: 0.310.10 the README's hooks paragraph shows what holds work back today.**The README's hooks paragraph shows what holds work back today** (PATCH; founder ruling 2026-10-03). It said four hooks could hold work back and that a bug fix never meets the discovery stop; both stopped being true. It now says what each kind of stop holds, without counts. Prior: 0.310.9 the evaluator pages say what Mycelium does today.**The evaluator pages say what Mycelium does today** (PATCH; docs north-star item 8, 2026-10-03). docs/evaluate.md and docs/usage-modes.md, last touched in May, are corrected claim by claim against the code; /mycelium:canvas-sync now stages .claude/diamonds/. Prior: 0.310.8 history of the retired phase loop no longer reads as the current model.**History of the retired phase loop no longer reads as the current model** (PATCH; warm-reader finding 2026-10-02, roadmap worksheets item 5b). docs/philosophy.md marks its four-phase history paragraph as a history aside (wording unchanged); docs/glossary.md drops the same history from the Diamond entry, which the Phase entry already marks retired. Prior: 0.310.7 the discovery page reworded where readers tripped, and it now shows a stop.**The discovery page reworded where readers tripped, and it now shows a stop** (PATCH; founder ruling 2026-10-02/03, roadmap DL-1399 to DL-1403). docs/mental-model.md: sentences that six rounds of simulated readers tripped on are reworded, and two short paragraphs say what a stop looks like and how it works on a team. Prior: 0.310.6 the file-viewer story says what actually happened.**The file-viewer story says what actually happened** (PATCH; founder ruling 2026-10-02, roadmap DL-1392). The README, the evaluate page and the receipt stop saying the file viewer was killed by asking real people or 'with evidence': per the project's own 2026-04-09 log it was stopped on six simulated users, which Mycelium graded as speculation, and the real interviews it listed next were never run. Prior: 0.310.5 the README opens with what Mycelium won't do.**The README opens with what Mycelium won't do** (PATCH; founder's words, 2026-10-02). README.md's first line becomes "Mycelium won't make your idea good. It keeps you and your agent honest about whether it is, from first idea to market.", matching the scope of the new GitHub About text, and the Start section links docs/get-started.md, which the README never linked. Prior: 0.310.4 the Definition of Done rationale is a page, not a design file.**The Definition of Done rationale is a page, not a design file** (PATCH; docs north star, founder ruling 2026-10-02). docs/design/definition-of-done.md moves to docs/definition-of-done.md as an explanation page with an audience marker; the four framework files that cite it (diamond-rules, define-done, canvas-health, a session-start comment) follow, and canvas-health stops saying a diamond 'reaches Deliver'. docs/design/ is empty and gone. Prior: 0.310.3 fewer pages, each with a reason to exist.**Fewer pages, each with a reason to exist** (PATCH; docs north star, roadmap DL-1386, founder ruling 2026-10-02). docs/faq.md and docs/receipts/archive.md are removed, the three receipts indexes become docs/receipts/index.md, docs/skills/by-category.md folds into the skills index (Check 6b and its sync entry go with it), and two unreferenced maintainer design plans move from docs/design/ to .claude/evals/design/. Every FAQ answer already had a home or gains one line. Prior: 0.310.2 reference pages say decisions, and two orphan pages get a way in.**Reference pages say decisions, and two orphan pages get a way in** (PATCH; docs north star, roadmap DL-1386). context-surface.md, the skills index and the agent operating contract stop describing a diamond by its retired phase: where a diamond is is read from its recorded decisions, and guardrails load by scale. The glossary gains a purpose-stance entry linking docs/purpose-stance.md, and the system card links docs/threat-model.md; neither page had a link from anywhere. Prior: 0.310.1 get started leads to running it on a project.**Get started leads to running it on a project** (PATCH; docs north star, roadmap DL-1386/DL-1387). docs/get-started.md is rebuilt by the Core Model worksheet: its goal is running Mycelium on a real project, with the four questions as the milestone on the way; it says what the brief writes and where, what to do after the menu, how to judge it over three projects, what it costs, and how to remove it, and stops linking the stale FAQ and evaluate pages. Three skills stop writing the retired phase on a new diamond (interview, launch-tier) or naming it (ost-builder). Prior: 0.310.0 the work-recording check reads the releases it counts.**The work-recording check reads the releases it counts** (MINOR; dogfood DL-1375). check_cycle_recording.py counts unprefixed release subjects ("0.310.0: ...") at the start of a subject, counts each version once, and reads the release repo from `thresholds.yml#cycle_recording_arc.release_repo`, so a consumer whose releases ship elsewhere is measured at session start; a configured path missing on this machine is a `release-repo-missing` status the hook relays. A thresholds.yml with no `thresholds` table is a calibration WARN instead of silence. The release arc is no longer reported as due for calibration: no rule exists for it, so its mapping to effort_accuracy is removed. Measured on the dogfood repo: the check read 1 release where 111 had shipped. Prior: 0.309.6 why Mycelium is opinionated, for the reader deciding.**Why Mycelium is opinionated, for the reader deciding** (PATCH; stage 6, DL-1369). docs/philosophy.md is rewritten for the evaluator asking why it is so strict: five reasons, each with one plain receipt, the multi-team scope in four sentences, and next steps; drafted by the agent from the founder's edit, voice-gated, and approved by him. The mechanics it carried (the framework loop, build mode, the single-team findings) move to architecture.md. Prior: 0.309.5 the reference docs and the README say what the code does.**The reference docs and the README say what the code does** (PATCH; stage 6, DL-1369). The README no longer says a weekend project skips layers (false since v0.247.0) and its footer names the page it links; glossary.md defines decisions, modes, positions and exposure records and retires Phase; theories.md places Four Risks and Cynefin at their decisions and credits Rother and dual-track for the loop, with what is Mycelium's own said as such; architecture.md loads domain context by the work at hand. Prior: 0.309.4 what discovery before the build gives you.**What discovery before the build gives you** (PATCH; stage 6, DL-1369). docs/mental-model.md is rewritten for the reader who has read the README and is not convinced yet: the measured case (randomised trials: the wrong project is stopped weeks sooner, not more often) and documented failure stories, drafted by the agent from three research sweeps and rewritten by the founder; the docs that point at it, architecture.md's diamond description and wayfinding's skipped-scale example are corrected. Prior: 0.309.3 every skill and rule says decisions.**Every skill and rule says decisions** (PATCH; stage 5d-3c, DL-1372). The remaining skills, engine and harness files, the journey map and the stop-check message speak in decisions and two modes; xai-check named the XAI gate at moves the code never asked it at; no verdict changes. Prior: 0.309.2 the gates and the diamond rules say decisions.**The gates and the diamond rules say decisions** (PATCH; stage 5d-3b, DL-1372). theory-gates.md and diamond-rules.md speak in decisions and two modes; the per-scale gate tables have one column per decision, and they and every gate's Applies-to line are now compared with the code (two Applies-to lines had said L2-L4 where the code requires L2-L5); no verdict changes. Prior: 0.309.1 a recorded decision stays recorded.**A recorded decision stays recorded** (PATCH; DL-1374, enforcing DL-1373). The scale-lock gate refuses a write that removes a recorded decision or changes its name or date, wherever the diamond now sits; notes, gates and rulings stay editable, a missing date may be filled in, and appending still passes. Prior: 0.309.0 a diamond moves by recording decisions, and is drawn as them.**A diamond moves by recording decisions, and is drawn as them** (MINOR; stage 5d-3a, DL-1372 V4, DL-1373). /diamond-progress speaks in decisions, names how a loop iterates (append another `start_experiment` or `commit_to_build`, never remove one) and no longer asks for `progression_history`; /diamond-render calls the new `render_diamonds.py`, which draws each diamond as its decisions in order, grouped by mode; no verdict changes. Prior: 0.308.2 session-start checks read this project, not copies of others.**Session-start checks read this project, not copies of others** (PATCH). The stale-prose and source-authenticity checks skip project snapshots kept under `.claude/` (a directory with its own `canvas/` or `.claude/`), and the second reads the project's own handles once per scan; the background tier no longer cites a timeout that does not apply to it. Prior: 0.308.1 what the agent reads is keyed by decision.**What the agent reads is keyed by decision** (PATCH; stage 5d-2, DL-1372 V2). confidence-thresholds.yml's approvals, thresholds and evidence, and theory-gates' Transition Matrix, are keyed by decision; the drift check compares the matrix with `scale_locks.DECISIONS`; no verdict changes. Prior: 0.308.0 Mycelium says where a diamond is by its decisions.**Mycelium says where a diamond is by its decisions** (MINOR; stage 5d-1, DL-1372). Messages and next items speak in decisions and the two modes ("target set", "committed to build", "released"; "record `release`" instead of "move to Deliver"); no verdict changes on the stage's frozen corpus. Prior: 0.307.9 a repair that cannot see a diamond's exposures is refused for it.**A repair that cannot see a diamond's exposures is refused for it** (PATCH, safety; DL-1371). Closes the residual 0.307.7 shipped with: the rulings record always says whether a delivering diamond has exposures, and a repair whose last good state cannot show them is refused for that diamond, with the remedy. Prior: 0.307.8 controls that test their rule.**Controls that test their rule** (PATCH; DL-1370 batch 4). Five controls the audit found passing for the wrong reason are rewritten with explicit records and checked against planted defects; a move's `progression_history` requirement, which could not fire since v0.306.0, is removed. Prior: 0.307.7 lifecycle.**Lifecycle** (PATCH, safety; DL-1370 batch 3). An L3 ended by archiving, by killing after parking, or by removal from the file says how its learning delivery ended; an L3 inheriting its L2's target closes when the L2 re-targets; a repair of a broken diamonds file is judged with the running exposures. Prior: 0.307.6 the build gate.**The build gate** (PATCH, safety; DL-1370 batch 2). A discovery-skip-ack lifts the cold-project gate only; an ack's scope and the declared prototypes cover every file a command writes; an L4 on a set names what it delivers, unwaivably; a diamond stamped `completed_at` without `close` carries nothing; the build refusal prints its remedy. Prior: 0.307.5 the release path's judgement.**The release path's judgement** (PATCH, safety; DL-1370 batch 1c). Closing an L5 that already delivers asks the person; a widening is judged once the L3 reaches people or may (a current or started exposure), not only after `release`; the Develop trial is an exposure, recorded first (ruling a); the prompt and change lines read readiness as the release gate does. Prior: 0.307.4 shell and file-move paths to the diamonds file.**Shell and file-move paths to the diamonds file** (PATCH, safety; DL-1370 batch 1b). A shell write that launches an L5 or records personal data is reported; naming Mycelium's own writer no longer excuses another write; moving the diamonds file away is refused, through the shell or MCP. Prior: 0.307.3 the release gate's inputs.**The release gate's inputs** (PATCH, safety; DL-1370 batch 1a). A project whose diamonds have all completed is judged; more releases are recognised (a list plus any command named for a deploy/publish); a non-ISO end date no longer keeps a record current; a structured skip-ack with no ISO date lifts nothing; personal data however written asks the person. Prior: 0.307.2 a completion with no `close` is judged again.**A completion with no `close` is judged again** (PATCH, safety). A diamond written into completed_diamonds without recording `close` read as not having moved and passed no completion gate (since v0.303.0 for diamonds with decisions, v0.306.0 for all): an L3 could complete with its learning delivery never ended. It is judged as a move to complete again, and the missing decisions are named. Prior: 0.307.1 what 0.307.0 still read in the old shape.**What 0.307.0 still read in the old shape** (PATCH). The scale-occupancy report counts an L2's recorded target only, as the lock does, and judges it closed by its state or `close` decision; the build gate's message reads where a diamond is from its decisions; /diamond-render, /metrics-pull and diamond-rules stop treating the `phase` label as the record. Prior: 0.307.0 the old object and delivery shapes are no longer read.**The old object and delivery shapes are no longer read** (MINOR, BREAKING). Phase migration stage 5c-2 (DL-1367 R4, DL-1368 S4). An L2 targets only its recorded `target`, an L3's front runner is only its recorded `front_runner`, and an L3's learning delivery is only its exposure record: `learning_delivery` is not read. The migration offer now comes right after fired proposals, listing every diamond the migration would change, and a started delivery nobody migrated stays in the exposure report. Prior: 0.306.0 the phase is no longer read.**The phase is no longer read** (MINOR, BREAKING). Phase migration stage 5c-1 (DL-1368 S4). Where a diamond is comes only from the decisions it records: a diamond with only a `phase` reads as discover, and a release needs an exposure record (the phase fallback is gone). `migrate_phase.py` converts a project, now reading the recorded field, carrying a closing phase into `state`, and judging its result against where the diamonds were recorded. Prior: 0.305.0 every reader of where a diamond is reads its decisions.**Every reader of where a diamond is reads its decisions** (MINOR). Phase migration stage 5b (DL-1368). The next item, the closing path, the purpose-stance check, the stop hook and the session-start outcome check read where a diamond is through `scale_locks.phase_of` (the decision log, the recorded phase only without one); /diamond-progress records each move's decisions with their gates, an L0 records `review` instead of moving and is never offered a move, migrate_phase.py migrates an L0 recorded `complete`, and /diamond-render draws from the decisions. Prior: 0.304.0 an L2 opens under the L1 that set its outcome.**An L2 opens under the L1 that set its outcome** (MINOR). 0.301.0's L2 door paired an unmapped outcome with the first L1 whose lock held, so with two L1s it named the wrong parent (the dogfood repo, 2026-10-01). An outcome now names its L1 in `set_by`; the door opens only under it, a new L2 under another L1 is refused, and with no name and several L1s the next item asks which. Prior: 0.303.0 a diamond records its decisions, and a migration moves the phase into them.**A diamond records its decisions, and a migration moves the phase into them** (MINOR). Phase migration stage 5a (DL-1368). Where a diamond is, is read from its decision log, the recorded phase only when it has none; an L0 records state_purpose and review. `migrate_phase.py` rewrites the phase history as dated, reconstructed decisions, a learning delivery as a reconstructed exposure record, and the old L2/L3 shape as the new fields, and writes only what the scale locks read as no change. No new refusals. Prior: 0.302.0 one L2 per outcome, one L3 per target, and re-targeting closes the old L3.**One L2 per outcome, one L3 per target, and re-targeting closes the old L3** (MINOR, adds blocks). Phase migration stage 4c (DL-1367 R2, R3). A second L2 on an outcome or a second L3 on a target is refused when it opens; an L2 that re-targets closes the L3 on its old target in the same write as `retargeted`; an L3 ended by its state (killed, archived, retargeted) says how its learning delivery ended, as a completion does; L5 results join the existing L2's map. Prior: 0.301.0 an L2 opens on an outcome and an L3 on its L2's target.**An L2 opens on an outcome and an L3 on its L2's target** (MINOR). Phase migration stage 4b (DL-1367, ruling C). The doors open per outcome and per target, not on a record from a pile: /ost-builder offers both, /ice-score compares the ideas inside an L3 and opens nothing. An L2 with no target is asked to choose one by comparison; an L3 stops when its front runner fails or none of its ideas works, never on one sibling; a diamond in the old shape is asked to record the new fields. Prior: 0.300.0 an L2 targets, an L3 commits a front runner, and the L4 reads what it delivers.**An L2 targets, an L3 commits a front runner, and the L4 reads what it delivers** (MINOR). Phase migration stage 4a (DL-1367). An L2 names its outcome and a current `target`; an L3 is that target and its solutions and names a `front_runner`; the old one-opportunity and one-solution shapes are read through a translation until stage 5. The L4 lock reads the verdicts of the solution it delivers: a validated sibling no longer opens it, and a failed sibling no longer blocks it. Prior: 0.299.0 the closing path says what each gate is owed before.**The closing path says what each gate is owed before** (MINOR). Phase migration stage 3b-2. Pending gates are grouped: owed before the next move's decisions (named), the safety gates that move needs, gates only a later move needs, and gates passed with a risk, which were listed as if owed. The purpose-stance check blocks from the decision to build (ruling e), read from the decision table. Prior: 0.298.0 the gates are keyed to the decisions they guard.**The gates are keyed to the decisions they guard** (MINOR). Phase migration stage 3b-1 (DL-1366). Each level's learning loop makes five decisions (set target, start experiment, commit to build, release, close) and each gate belongs to the one it guards; a phase move makes a fixed set of them, so it needs the same gates as before, pinned cell by cell against 0.297.0. A move's history entry names its decisions. Prior: 0.297.0 the gates a diamond is born with agree with the gates its moves require.**The gates a diamond is born with agree with the gates its moves require** (MINOR). Phase migration stage 3a. An L5 is born with Privacy and Service Quality, which its moves have required since 0.292.0 (ruling f); Delivery Metrics is no longer required when an L5 closes, as the gate's own definition and 0.235.0 say; and the drift check compares every born list with the per-transition table, so the two sources cannot part again unseen. Prior: 0.296.0 an L3's learning delivery can be its exposure record.**An L3's learning delivery can be its exposure record** (MINOR). Phase migration stage 2b. Every rule on an L3's learning delivery (its fields, its end date, how it ended, a change to its audience, end date, channel or data) reads `learning_delivery` when the diamond carries it and its exposure record otherwise, so one record serves both; recording an exposure is not a start, and the messages name the record in use. Prior: 0.295.0 the release gate reads exposure records.**The release gate reads exposure records** (MINOR). Phase migration stage 2 (DL-1365). In a project that records exposures, a release needs a current record (in date, its fields filled, Security, Privacy and Service Quality passed for it, on a diamond whose chain holds): one allows it, several ask the person which, none refuses with the reasons. A project with no records yet keeps the phase check and is told to record one. Contract rule 14 says the same. Prior: 0.294.0 exposure records: who the work reaches, recorded on its diamond.**Exposure records: who the work reaches, recorded on its diamond** (MINOR). Phase migration stage 1. A diamond whose work reaches people carries `exposures[]` (audience, channel, data class, end date, consent, the gates passed for it); `scale_locks.py --exposures` reports the gaps and blocks nothing yet, and a write that adds an exposure with personal or sensitive data asks the person (ruling g). Prior: 0.293.0 the delivery skip-ack is a dated, scoped record.**The delivery skip-ack is a dated, scoped record** (MINOR). Phase migration stage 0b-3b, founder ruling DL-1364. The file's mere existence lifted the build and release gates for all work, forever, and it was gitignored. Now it lifts the build gate only for the paths it `covers`, a release only when it says `releases: true`, expires after 30 days by default, logs every use, and setup keeps it in git; an old bare file is honoured for 14 days with a warning. Prior: 0.292.0 an L5 launch asks a person; the gate table carries XAI and L5's privacy and service quality.**An L5 launch asks a person, and the gate table carries XAI and L5's Privacy and Service Quality** (MINOR, adds blocks). Phase migration stage 0b-3a. The L5 human-approval floor was prose no code read; a write that moves an L5 into deliver or complete now asks in the permission dialog, and is refused where nobody is asked. The explainability gate joins the table the phase gates read (L3-L5, only with AI components), L5 needs Privacy and Service Quality before it delivers, the drift check compares the per-transition table with the code, and an id used as a map key no longer trips the key-shape guard. Prior: 0.291.1 an override citing a recent decision is no longer read as dangling.**An override citing a recent decision is no longer read as dangling** (PATCH). The purpose-stance check found decision IDs only when a heading began with one; the dogfood log's date-first headings (`## 2026-09-24 — DL-1361: ...`) since about DL-1286 were invisible, so it reported 236 IDs and missed the newest 77, and a founder override citing DL-1363 read as dangling. Prior: 0.291.0 editing product code counts as building; an exposed pilot cannot widen unseen.**Editing product code counts as building, and an exposed pilot's record cannot widen without its gates** (MINOR, adds blocks). Phase migration stage 0b-2; the last two run-10 holes. Once discovery is engaged, Edit, MultiEdit and the MCP edit tool are gated like new files, except under declared `prototype_paths`. An exposed L3's learning delivery that extends its end date or changes its channel or data needs a recorded change with the gates re-run. Prior: 0.290.0 the release gate closes three holes, and the safety gates refuse when they cannot read.**The release gate closes three holes, and neither safety gate lets work through when it cannot read the canvas** (MINOR, adds blocks). Phase migration stage 0b-1. Without PyYAML the release gate allowed and the build gate refused for a false reason; both now refuse and name the fix, and they use Mycelium's own environment (created by /mycelium:setup on request, in the plugin's data directory) when the PATH python3 lacks PyYAML. The release gate counts tunnels and a push to a host that publishes on push, and stops counting release verbs that are only carried as text. Prior: 0.289.0 the safety net pinned before the phase migration.**The safety net pinned before the phase migration** (MINOR). Stage 0a of the migration ruled 2026-09-30: E2E run 10 (an SMS app built and put live under an L3 in define) is replayed on every release as a permanent test, and five holes open today are strict expected failures that stage 0b must close (editing product code, a tunnel, a push to a host that goes live on push, widening the audience, and the release gate failing open without PyYAML). stop-check reads the YAML instead of substrings, the outcome check sees completed_diamonds, exposure-change also runs after MCP writes, and version-discipline says what a breaking change is before 1.0.0. No new blocks. Prior: 0.288.1 a stored next item that is stale or settled is not offered again.**A stored next item that is stale or settled is not offered again** (PATCH). The prompt, resume and Stop hooks read `.claude/state/next-item.json`, which only session start rewrites, and checked only ledger rulings: the dogfood state, written by 0.254.1, kept offering `fired:ht-046` six days after it was ruled in active.yml. Every reader now shares one check: a state from another release is silent until the next session start, and a fired proposal is settled once the record no longer offers it. Prior: 0.288.0 an override never waives what an L4 delivers.**An override never waives what an L4 delivers** (MINOR). The scale-lock override could waive an L4's whole chain, so an L4 with no L3 behind it and nothing named as its object passed the lock; the dogfood L4 shipped five months of releases that way. An override may still waive the L3 and its evidence, which is the user's call to ship an untested bet, but an L4 with no L3 must name the solution it delivers in `object_ref`, and no ack lifts that. Prior: 0.287.2 a released L4 with its launch data recorded is told what the L5 lock still misses.**A released L4 with its launch data recorded is told what the L5 lock still misses** (PATCH). The next item asked for launch data whenever the L5 lock failed and a release date existed, so an L4 on an override with no L3 parent, released and with its launch data recorded, was asked to record it again and the missing parent was never shown. It now names what the lock reports, and the picker honours `state: archived` (or parked, killed) as closed, as scale_locks already did. Prior: 0.287.1 a closing-path proposal ruled on the record stops being offered.**A closing-path proposal ruled on the record stops being offered** (PATCH). diamond-assess tells the agent to settle a CLOSING PATH FIRED proposal that chooses no path by writing `ruling:` and `ruled_at:` under it, and derive_closing_path keeps those keys; the next-item picker never read them, so the dogfood L1 offered `fired:ht-046` as its top item for 13 days after the ruling. Ruled entries are now skipped; unruled ones still come. Prior: 0.287.0 a leaf's missing record is said at the write, and moved entries keep their address.**A leaf's missing record is said at the write, and moved entries keep their address** (MINOR). The dogfood canvas's remaining validator warnings traced to two sources. Leaves written straight into opportunities.yml reached a terminal status with no cycle row (23) or arrived with no purpose stance (7), and the validator named them days later; `post-write-nudge.sh` now names what the leaves a write touched still owe, at that write. And 11 of 13 dangling pointers named entries the canvas's own restructures had moved into lists (`moved_from`, `former_key`, `leaf_id`, `kind` plus `date`, the shape the key-shape guard recommends), schema notation, or a plugin engine file; the resolver now reads all of them. Prior: 0.286.3 on Codex, the next item names a skill the way Codex users type it.**On Codex, the next item names a skill the way Codex users type it** (PATCH). Codex lists Mycelium's skills as `mycelium:x` and its users mention a skill with `$`, while every item said `/mycelium:x`. The human line now renders `$mycelium:x` when the hook runs under Codex (`MYCELIUM_RUNTIME=codex`), and the operating contract tells the agent the mapping. Prior: 0.286.2 Codex logs shell reads too.**Codex logs shell reads too** (PATCH). `read-log.sh` took `Read|Bash` on Claude Code since v0.143.0 and `Read|read` in the Codex file, and Codex has no Read tool, so on Codex no read was ever logged and `verify_citations.py` had no ground truth for what the agent opened. A matcher-parity test now compares every hook's tools across the two files, with the by-design differences named. Prior: 0.286.1 a file written by an interpreter one-liner is a write.**A file written by an interpreter one-liner is a write** (PATCH). On Codex CLI 0.158.0 with Mycelium's hooks trusted, the shell hooks ran, and the agent still created app/hello.py in a project with no discovery, through `python3 -c 'Path("app/hello.py").write_text(...)'`: the shell-write parser recorded a write_text with no path, and the discovery gate skips those. A literal path in `Path(...).write_text/bytes` or `writeFileSync(...)` is now a target, quoted or escaped. Prior: 0.286.0 Mycelium on Codex runs its own hooks, and says when none run.**Mycelium on Codex runs its own hooks, and says when none run** (MINOR). Measured on Codex CLI 0.158.0 from the marketplace: all 63 skills loaded; with the hooks untrusted no hook ran and a source file was written with nothing said; with them trusted the session-start contract held. A new `.codex-plugin/plugin.json` points Codex at a hooks file derived from hooks.codex.json (without it Codex fell back to hooks.json and would drop its four async hooks); the guard for off-switch files refuses on Codex, which turns a hook's ask into an allow; the entry skills check a marker the hooks write and tell the user when it is missing; and start's first check no longer reads an unset CLAUDE_PROJECT_DIR. Prior: 0.285.0 a snoozed door wakes when the product changes.**A snoozed door wakes when the product changes** (MINOR). In the E2E relay on 0.283.0 the builder added features to the recipe code by editing an existing file, the founder snoozed the L1 door "until asked", and nothing was offered for the rest of the run while the product was built outside the ladder; service run 10 went silent the same way for 12 sessions. A snooze until asked on a way into the ladder, or on the ladder itself, now ends when a product file changes after the ruling, not counting what the ruling session wrote; the item says why it is back. Evidence does not wake it, and other items and dated snoozes keep their ruling. Prior: 0.284.0 the outside trial is Develop's, not a release.**The outside trial is Develop's, not a release** (MINOR). In the E2E relay on 0.283.0 the L3's Develop -> Deliver gate asked for one trial outside the team of what the delivery puts in front of people, and the exposure line said nothing built may meet real people before Deliver; the builder read both correctly and refused to let one tester paste a recipe into the page, so the gate could only pass by the founder running the trial behind Mycelium's back. While an L3 is in Develop the exposure line now names that one trial as Develop's own evidence, and the L3's Deliver item says it comes first. Prior: 0.283.0 an untried opportunity's door comes first.**An untried opportunity's door comes first** (MINOR). In the E2E service run 9 two L2s could open an L3; Mycelium offered the first in file order, whose L3 had completed and whose solution was already in production, session after session, and never the untried L2 the new L5 was about; the founder had to ask for it herself. Among parents whose lock holds, one that never had a child at that scale is now offered first; file order holds within each group, and the served one still comes next. Prior: 0.282.0 Deliver is not released.**Deliver is not released** (MINOR). In the E2E relay on 0.280.0 the L4 reached Deliver with the founder's public post on hold, and the next item said "has shipped" and told the agent to record the release seven sessions running; the builder rightly declined, since nothing had gone out. The shipped-L4 item is now three steps: with no `released_on` it is the founder's, to say when the L4 reaches its users; once released, recording the launch data is the agent's; once the lock holds, the L5 door. Prior: 0.281.0 an off-switch is the user's to write, in every project.**An off-switch is the user's to write, in every project** (MINOR). In the E2E relay on 0.280.0 the builder, running with permissions bypassed, wrote its own scale-lock override ("My judgment call, my override") and opened an L4 past its lock. A write to a file that switches a gate off returned `ask`, and in that mode nobody is asked; the three guards that asked were each conditional, so an ordinary project had no guard on the ack files at all, while the scale-lock docs said the agent gets an ask. A new gate in every project asks where a person is asked and refuses where nobody is. Prior: 0.280.0 an item only its doing can answer is not snoozed until asked.**An item only its doing can answer is not snoozed until asked** (MINOR). In the E2E service world run 7 the pilot's start item was snoozed "until real first-month-end data lands", data that exists only after the pilot starts, and the item for a delivery past its last day was snoozed the same way; the founder asked for the same month-end data six sessions running and nothing said the pilot had never started. The ledger now refuses a snooze until asked on the start, deliver and delivery-over items and accepts a date; and a refused ruling exits 2, where it exited 0 and read as recorded. Prior: 0.279.0 a write that ends exposure is said at once.**A write that ends exposure is said at once** (MINOR). In the E2E rung L4-open on 0.278.0 one builder turn completed the L3 as handed to a new L4 still in discover, which left nothing cleared for real people, and then called the founder's public launch post "ready to post whenever you are"; she posted it. The exposure line speaks only at a prompt, and the state flipped inside the turn. A new advisory PostToolUse hook, exposure-change.sh, tells the agent right after the write that took the work from ready to not ready, with what is missing, once. Prior: 0.278.0 a gate never evaluated is pending, not passed.**A gate never evaluated is pending, not passed** (MINOR). E2E rung L4-define on 0.276.0 assessed an L4, ruled needs-evidence and wrote no gate result, since the skill's only instruction to record gates sat under the phase move; the closing path then printed "every gate reads pass; nothing to store" for a diamond with no gate status at all, and the L4 sat in discover for three sessions. The closing path now counts every gate the next transition needs and has no status as pending, the agent's to evaluate now, and /mycelium:diamond-progress records each gate's result on every outcome. Prior: 0.277.0 a test past its score date is scored by Mycelium.**A test past its score date is scored by Mycelium** (MINOR). In the E2E rung L4-open on 0.276.0, 4 of 5 testers came back against a frozen bar of 3; the builder offered to write the result ("say the word") and did not, the verdict item fired only on a file already marked scored, and 0.276.0's ladder line "It waits on its learning delivery ending" was read as the whole L3 waiting and snoozed. An L3 test still live past its `score_by` is now the agent's to score from the notes, or to re-date with the reason; the ladder says only the move waits, not the verdict; and the line beside the request, which told the builder to put every escalated item to the user, now says to do an agent's item, from the first session (rung L5-open on 0.276.0 asked the founder to rule on the launch record). Prior: 0.276.0 a move that can happen now is proposed first.**A move that can happen now is proposed first, and an item says what to do** (MINOR). E2E rungs on 0.275.x: an L3 whose pilot was still running led the ladder every session because its notes kept arriving, and the L4 whose next move was desk work waited below it (L4-develop reached develop 1 of 3); the L4 was opened with no bar and two sessions went on asking the founder to write one she had decided; and the launch-data item borrowed the verdict's instruction, so the builder held the launch figures two sessions asking "say the word". A move that waits on the world (an L3 whose learning delivery has not ended) now follows one that can happen now; a bare L3-L5 gets its definition of done drafted from the founder's decisions, for her to confirm; and an agent-owned item carries its own instruction. A learning delivery past its last day now asks how it ended whatever was snoozed before (service world run 5 ran a month past it, clients still paying, no L4), and a hand-typed `ended.on` is read: `on` is a YAML 1.1 boolean and loaded as the key True. Founder: propose a move once what it needs is on record. Prior: 0.275.1 recording the launch is Mycelium's work.**Recording the launch is Mycelium's work, and the item names the fields** (PATCH). In the E2E rung L5-open on 0.275.0 the shipped-L4 item was put to the founder for four sessions, and the builder wrote the launch figures into a log entry the L5 lock never reads. Until the release and its launch data are recorded, the item is the agent's and names `released_on` and `launch_data: {..., as_of}` on the L4; the L5 door stays the founder's decision. Prior: 0.275.0 launch data comes after the release.**Launch data comes after the release** (MINOR). In the E2E rung L5-refused, with the launch withheld, the builder wrote the L3 pilot's five-tester results into the L4's launch_data ("forum page opens: 0") and the L5 lock, which read only that usage was filled, opened the L5. The L4 now records `released_on`, and the L5 lock needs `launch_data.as_of` after it. Prior: 0.274.0 a learning delivery's start is on the record.**A learning delivery's start is on the record** (MINOR). The E2E service world's L3 reached Deliver and grew its client pack from 4,100 to 7,100 words over seven sessions while nobody was served; 0.273.0 caught a growing build only in develop. `learning_delivery.started` records the day the first person took part; until it is set, the next item offers the start, and once overdue tells the agent to cut the build to what the start needs. Prior: 0.273.1 a duplicate key is named as it is written.**A duplicate key is named as it is written** (PATCH). YAML keeps a duplicate key's second value and drops the first without a word; the full canvas validator reported it, the check that runs as a file is written did not. The E2E service world wrote three into threat-model.yml and nothing told the builder. Prior: 0.273.0 an L3 builds only what its test needs.**An L3 builds only what its test needs** (MINOR). The E2E service world grew 8,500 words of client documents for a two-month, hand-run pilot with three existing clients, each edge case a new question for the founder, and the pilot never started. The L3's learning-delivery item now says to build only what the test needs, and once overdue tells the agent to stop extending the build and send every other open question to the tree as the next assumption, or to L4. Founder: "that's the ost working its way." Prior: 0.272.0 Mycelium records its own verdicts.**Mycelium records its own verdicts** (MINOR). In the E2E service world the pilot met the bar its test was frozen with, and the verdict item was put to the founder for three sessions as "Decide one: run | rule | snooze | drop"; the builder left it for her, nobody wrote it, and the L4 stayed locked. A next item now says whose it is: recording a verdict is the agent's to do now, told to the founder as being recorded; a door, a release or a pivot stays the founder's decision. Prior: 0.271.1 the security scope has its own key.**The security scope has its own key** (PATCH). 0.271.0 recorded the scope under `scope`, the name threat models already use for their sentence on what is modelled, so the E2E service world's threat model failed the canvas check on its next write. It is `security_scope` now; a written `scope` is valid again. Prior: 0.271.0 security and privacy checks fit what the product holds.**Security and privacy checks fit what the product holds** (MINOR). Founder: "2fa and so on might not be applicable for all products." `/mycelium:security-review` now records the product's scope first (runs code, accounts, personal data, money, reach) and applies only the checks it calls for, the rest recorded n/a with a reason; a service handled by people has its own section; privacy controls are proportional; and theory-gates no longer calls an offline service's Security gate N/A, which the lock could never honour. Prior: 0.270.0 the delivery gate sees a product that is not code.**The delivery gate sees a product that is not code** (MINOR). The E2E second world, a bookkeeping service with no software, wrote its client agreement, intake checklist and price sheet with only an L0 in discover; the gate knew code by its extension and skipped every document. A project now records `product_paths` (where its own files live), new files there are gated whatever their kind, and the next item asks once an L0 exists. Prior: 0.269.0 evidence and test sizing fit the product type.**Evidence and test sizing fit the product type** (MINOR). The rest of the overfit audit: the L4's per-transition evidence is keyed by product type (a course, an AI tool or a service is no longer asked for code tests); the L3's Develop->Deliver asks for one trial outside the team in the form the product takes, not a software prototype; and test sizing records reversibility, reach and harm, derives the class from them, and reports a test too light for its decision as well as too heavy, with the decision owner able to accept either with a reason. Prior: 0.268.0 the learning-delivery rules fit builders beyond the test world.**The learning-delivery rules fit builders beyond the test world** (MINOR). An audit of 0.258.0-0.267.0 against eight builders (a course pilot, a concierge service, a hardware loan, an internal team, a staged app beta, an open-source pre-release, a non-English founder, a project without git) found the 0.267.0 rules shaped to one simulated web page. How a delivery ended is recorded as fields, never matched as words; an audience change is recorded with its kind (narrowed, reworded, widened with its gates re-run, or everyone, the L4's); a repair reads the fresher record before the commit; an inconclusive test and a delivery past its end date each get a way on. Prior: 0.267.0 an L3's learning delivery keeps its audience.**An L3's learning delivery keeps its audience, and ends when the L3 does** (MINOR). The E2E rung L4-open made its page public under the L3, on Security and Privacy passed for five testers, and completed the L3 with the page still up. Widening the audience of an L3 that delivers now needs an L4 on it; an L3 completes by recording how its learning delivery ended (taken down, or handed to its L4); a completion written straight into completed_diamonds is judged like any move; and the L4 door names the audience it is the way past. Prior: 0.266.0 a broken diamonds file can be repaired.**A broken diamonds file can be repaired** (MINOR). The E2E rung L4-ship broke diamonds/active.yml with a shell write; the shell check said to fix it with Edit, and the scale lock refused the Edit as opening every diamond in it, since a file that does not parse read as no diamonds. A repair is now judged against the last good state (the committed file, else the scale and phase Mycelium recorded); anything the repair changes is still judged. Prior: 0.265.0 a verdict the lock cannot read is asked for again.**A verdict the lock cannot read is asked for again** (MINOR). An E2E rung recorded a correct pass as prose ("met on 2026-11-18 ... 4 of 5"); the L4 lock reads only its own words and stayed shut, and the verdict item stood down because the field was not empty. It now fires on an unreadable verdict and asks for `validated` or `invalidated`, reasoning in `verdict_note`. Prior: 0.264.1 the lock verdicts are pinned against reordering.**The lock verdicts are pinned against reordering** (PATCH). Metamorphic tests: reordering diamonds, opportunities or solutions, or adding a parked diamond elsewhere, never changes which diamonds hold or whether the L4 and L5 may open. Tests only. Prior: 0.264.0 a test is sized to the decision it informs.**A test is sized to the decision it informs** (MINOR). E2E runs 53-55 pre-registered a re-test for a five-tester recipe page that needed twelve blind recipe lines and a government dataset, and stalled on inputs nobody could supply. `/mycelium:assumption-test` now classes the decision (light, standard, heavy) and picks a test no heavier; the instrument check reports OVERSIZED tests; the founder can override with a written reason. Prior: 0.263.0 a failed assumption offers the way on.**A failed assumption offers the way on** (MINOR). E2E run 53 recorded `invalidated` on its L3's riskiest assumption; the L4 lock refused correctly and the next session offered nothing. A new next item offers the three exits: revise and re-test (back to define), the next solution from the L2, or stop the L3 with a reason. Prior: 0.262.0 the L3's JTBD and Privacy gates are phased too.**The L3's JTBD and Privacy gates are phased too** (MINOR). E2E run 50 held its L3 in discover on JTBD `fail` ("the emotional and social sides are unknown") and Privacy `pending` ("can't pass until the page is built"), two design-time gates read as needing evidence from use. Their L3 rows now say what each transition asks: JTBD, the three dimensions stated to define and served by the design to develop; Privacy, privacy by design on the design to develop and the build checked against it to deliver. Prior: 0.261.0 the L4's threshold is its exit bar too.**The L4's threshold is its exit bar too** (MINOR). E2E run 47 held the first L4 any run has opened in discover at confidence 0.15 against 0.7: the L4's field started at the default and its threshold was read at its first transition, duplicating the lock that had just admitted it on a test-validated verdict. The L4's threshold now applies at deliver -> complete, and each transition names its own evidence. Prior: 0.260.0 a scored test asks for its verdict.**A scored test asks for its verdict** (MINOR). E2E run 46 delivered its L3 to five testers, 4 of 5 came back against a bar of 3, and the builder scored the test file; it never wrote the verdict on the riskiest assumption, which is all the L4 lock reads, and nothing asked for it. A new next item names the scored file and asks for the verdict, and the verdict is defined on the bet the solution needs, whichever way the statement is worded. Prior: 0.259.0 the L3's bars rise with its phases.**The L3's bars rise with its phases** (MINOR). E2E runs 42-43 held an L3 in discover for three in-world months: its 0.75 confidence threshold and "prototype tested with users" were read at every transition, so it could not define before it had the prototype it exists to produce, a higher entry bar than the L4's. The L3's threshold is now its exit bar, and each transition names its own evidence: a real problem to define, a named test to develop, a prototype met by users to deliver, the learning delivery's verdict to complete. Prior: 0.258.0 the L4 opens only on the verdict of a learning delivery.**The L4 opens only on the verdict of a learning delivery** (MINOR). E2E run 41 scored a hand-run trial at a real site with its L3 still in develop and the backup approver timed without being told; one recorded verdict would have opened the L4, and only the builder held it back. The L4 lock now also needs the L3 in Deliver with `learning_delivery` recorded; any means counts, a concierge or hand-run test included, and after an early pass the next item keeps proposing the L3's Deliver. Prior: 0.257.1 commands Mycelium shows run this plugin's own script.**Commands Mycelium shows run this plugin's own script** (PATCH). The next item named `advisory_ledger.py` with no path; in E2E run 32 the agent searched for it, ran a copy 37 versions old from the plugin cache, and the founder's answer was stamped with a date before the question, so the item kept escalating after it was answered. Every shown command now carries the plugin's absolute path, and the answer prompts say which ruling fits which answer ("not now, ask me after X" is a snooze until asked with X as the note). Prior: 0.257.0 the L3 delivers to learn, the L4 to earn.*
+ *Version 0.325.0 -- **A shell command's change to the diamonds file is put back** (MINOR; 2026-10-15). `hooks/bash-state-guard.sh` judged `.claude/diamonds/active.yml` by the command's text: a script that opened the file itself replaced a whole definition of done with nothing said (dogfood 2026-10-14), and a heredoc that only mentioned the path while appending to another file was refused. Now the file is compared around every shell command: a change is put back, the command's version kept under `.claude/state/bash-guard/put-back/` and named, and the person and the agent told which diamonds it touched. Not put back: Mycelium's own writers run on their own (the plugin's own copy, not the name), the person's override, and git leaving the file as committed at HEAD unless the same command committed a change to it. The text refusal keeps only writes whose target is the file. Prior: 0.324.0 -- **The scope hold is switched on by the delivery cycle that needs it** (MINOR; 2026-10-13). Until now `hooks/scope-gate.sh` read the folders it holds the agent's writes to from `.claude/state/active-execution.json`, which nothing Mycelium ships wrote, so in a plugin install the hold was never on. Now a delivery cycle (an L4) names them on its own record when it commits to build (`in_scope_paths` in `.claude/diamonds/active.yml`; an empty list is "no hold"), the write is put to the person, and a commitment to build with nothing said is refused. While the cycle is open a write outside the folders is put to the person with the file named (it was refused outright before), and refused where nobody is asked; a write that changes or removes the folders is put to them too; the hold ends when the close is recorded. A shell command no hook can read could delete the record or take the folders off it unseen (found while building, by trying it): `bash-state-guard.sh` now keeps a copy of the diamonds file per command and puts the whole file back when the command changed what a cycle names, and tells the person (maintainer's ruling 2026-10-13); a change that came through the edit tools meanwhile is kept. REMOVED: the old state file is no longer read, and while one exists product writes are refused with what to do (his ruling, so that a hand-set hold is not dropped in silence); `out_of_scope_paths` and the `spec` nesting have no counterpart; the `diamond_id` label the two logs took from that file is gone. A cycle that committed before this release is not held, and session start names it. Pages, skill, schema, rules page and contract carry it. Shown by a replay of fourteen writes through the shipped hook (`tests/python/test_the_scope_hold_through_its_hook.py`), not by a real delivery cycle; the put-back is a check on drift, not a sandbox. Prior: 0.323.2 -- **The pages stop describing a scope check nothing switches on** (PATCH; 2026-10-13). `hooks/scope-gate.sh` holds the agent's writes to the paths named in `.claude/state/active-execution.json` and leaves at once when that file is absent. No skill, script or hook writes the file, so in a plugin install the check has never been on (a blind reader of the installed plugin, dogfood 2026-10-11). README.md stopped claiming the hold in 0.322.3. Five other pages went on describing it as working (`docs/ai-system-card.md`, `docs/context-surface.md`, `docs/nobody-used-it.md`, `PRIVACY.md`, `plugins/mycelium/hooks/README.md`), this repository's own `.claude/state/README.md` named `/diamond-progress` as the file's writer, and two refusals of `scripts/scope_check.py` told the reader to run that skill to "recreate" a file it never writes. Fixed, words only: each page says the check is off unless you write the file yourself; the system card lists it under known limitations; the maintainer's page no longer mentions it (his wording, chosen 2026-10-13); the helper's messages say repair or delete the file. The gate itself is unchanged: a state file written by hand is still held to. The mechanism that would switch the check on (the folders kept on the delivery cycle's own record) has passed a replay in a scratch copy and is its own delivery work; the maintainer chose to make the pages true first. `tests/python/test_the_pages_say_the_scope_check_is_not_switched_on.py` (14 cases; 10 fail on the 0.323.1 pages) holds pages and plugin together both ways: it fails if a page drops the admission while nothing shipped writes the file, and fails the other way the day something does. Prior: 0.323.1 -- **Mycelium's own tests pass its own commit scan, and the printed hook lines no longer lock out a machine without the scanner** (PATCH; 2026-10-13). 0.323.0 added a scan of what is committed and pushed and was never run over Mycelium's own tree. Run the day after (dogfood 2026-10-13): gitleaks flags eight lines in four test files, made-up values in the shape of real credentials, so the scan refused any commit that touched them; the 0.323.0 release commit added two of those lines and passed only because the session that made it still ran the older hooks. Second fault: for a clone that already has a pre-commit hook, `scripts/install_git_secret_hook.py` printed a line to add to it, and that line exited 1 when gitleaks was not installed, refusing every commit there, where the hook the script writes itself says the commit was not scanned and lets it through. Fixed: the written hook and the printed lines are one block (`SCAN`); the test values are put together from two halves at run time, or are plain text where the value was incidental (K6 in `tests/bash/test_hooks_adversarial.sh` is renamed for what it checks: a write the gate cannot read is refused). No ignore file, scanner configuration or allow comment was added. New: `tests/python/test_no_tracked_file_trips_the_secret_scanner.py` stages every tracked file in a throwaway repository and asks the shipped `commit_scan.scan_staged` about it (red on the eight lines before the fix; skipped where gitleaks is not installed, which includes CI; the fallback list matches one tracked line, the key a holdout eval scenario hands the agent on purpose, left as it is); three tests run the printed lines with no scanner, with a scanner that finds nothing and with one that finds something. Each edited test was shown to still go red when the behaviour it checks is switched off. Prior: 0.323.0 -- **Secrets are stopped at the commit and the push, by an established scanner** (MINOR; 2026-10-12). Until now Mycelium looked for secrets when the agent WROTE a file, with a short list of its own. Replayed 2026-10-12: an unquoted `KEY=value` passed, an env file was treated like source code, and nothing looked at what was staged. The maintainer: "Don't let passwords into the repo"; "using established scanners are the way to go"; and, asked each in turn, "Stop refusing writes", "Fall back, and say so", "Agent must ask you first", then to the whole design said back, "Build it now". NOW (`scripts/commit_scan.py`): before the agent's `git commit`, what the commit would take is scanned (the index; with `-a` or a named path, tracked files as on disk); after any shell command, commits the command itself made are scanned, read from HEAD's reflog (`bash_state_guard.py`), and a finding is said and the commit left alone; before the agent's `git push`, every commit on a local branch that is on no remote is scanned. A finding refuses the commit or the push and names file and line, never the value. The scanner is gitleaks when installed; without it Mycelium's own list (`scripts/_secret_patterns.sh`, run by `_secret_grep.sh`) runs and the person is told once a session it is the weaker check. A scan that cannot run refuses. REMOVED IN THE SAME RELEASE: the scan of a file write in `hooks/gate.sh`. The agent may write a key into a file; it may not commit or push one. KEPT: a key typed into a shell command is refused. GUARDED: `.gitleaksignore` and `.gitleaks.toml` join `GUARD_STATE_REL`, and a write adding a `gitleaks:allow` comment asks the person. OFFERED, NEVER UNASKED: `/mycelium:setup` offers `scripts/install_git_secret_hook.py`, a pre-commit hook for commits made by hand; it never overwrites one that exists. README.md carries the maintainer's chosen sentence; PRIVACY.md, the system card, the hooks reference, the guardrails and the operating contract say the same. NOT SHOWN: any of it on Linux or Windows, or in a live session; a folder held in a shell variable; a `gitleaks:allow` added by a shell command. The scan follows the folder a command names (a `cd` before the commit, `git -C <folder>`), so a commit made in another repository is scanned there. `tests/python/test_secrets_are_stopped_at_the_commit.py`: 64 cases; `test_the_secret_scan_covers_dot_claude.py` is retired with the behaviour it pinned. Prior: 0.322.7 -- **The pages say what the build gate does not see** (PATCH; 2026-10-12). README.md said "the agent cannot create a brand new source file" and that building waits "new files and edits alike". The build gate judges a write it can read (the edit tools and plain shell writes); a command the agent runs that writes the files for it gives the gate nothing to read. Replayed on 0.322.3 by a blind read and again on 0.322.6, in a project where a plain redirect to a new source file is refused: a scaffolder, `npm init`, `cargo new`, `git clone`, `curl -o`, a script that writes, `patch` and `git apply` each pass with nothing said. NOW: no gate changes. README.md says the limit beside the claim, in the maintainer's chosen wording ("That covers the files the agent writes itself. A command it runs that writes them for it, a scaffolder or a clone, still gets through."), and `docs/ai-system-card.md` lists it under known limitations with the eight commands named. WHY NOT THE FIX: a before-and-after comparison through git held in three desk tests and in a scale benchmark on one Mac; the maintainer was not sure of it on Linux and Windows, and parked it until real users say which platforms they are on. NOT CHANGED: `docs/get-started.md` and the plugin description carry the same claim in softer words and were left as they are by the maintainer's choice. `tests/python/test_the_pages_say_what_the_build_gate_does_not_see.py` holds pages and gate together both ways: it fails when a page stops saying the limit, and it fails when the gate starts refusing one of the eight, with the instruction to take the sentence out. Prior: 0.322.6 -- **A Mycelium switch in a Claude Code settings file is the person's to set** (PATCH; 2026-10-12). Three environment variables loosen a Mycelium stop (`MYCELIUM_GUARD_STATE_EDIT`, `MYCELIUM_NEXT_ACTION_CHECK`, `MYCELIUM_TODAY`), and a hook cannot tell who set a variable. Claude Code takes variables from the `env` block of a settings file and re-reads the file mid-session, and two more keys there end every hook (`disableAllHooks`, and `enabledPlugins` with the plugin set to false). No Mycelium gate looked at a write to those files: replayed 2026-10-12 on 0.322.1, a tool call that put the override into `.claude/settings.local.json` drew no decision, while a write to `discovery-skip-ack` in the same replay was asked about. NOW: new `scripts/settings_switches.py` reads the Mycelium switches in a settings text (every `MYCELIUM_*` variable, `CLAUDE_PROJECT_DIR`, `CLAUDE_PLUGIN_ROOT`, and the two keys). `guard-state-gate.sh` works out what a file tool would leave in `.claude/settings.json`, `.claude/settings.local.json` or `~/.claude/settings.json`; a new switch, or a changed value, asks the person and is refused where nobody is asked; an edit that sets none is not asked about. `bash-state-guard.sh` notes the switches before each shell command (names and values, never the file) and afterwards takes a new one out again, keeping the rest of the file, the home-folder file included (maintainer: "Undo that line, tell me"); the plugin switched off in `enabledPlugins` is reported and left, because Claude Code's own plugin commands write that key. The person's override is read as it was BEFORE the command, so an override the command wrote cannot switch off its own undoing. COST: setting any `MYCELIUM_*` variable through the agent now costs one answer; a switch the person adds by hand while the agent's shell command runs is taken out with the rest. NOT SHOWN: any of it in a live session or in any permission mode; that hook commands receive the `env` block is Claude Code's documentation. NOT COVERED: variables that change how a shell starts (`BASH_ENV`, `PATH`), an edit through a symlink not named `settings.json`, Cursor's and Codex's own settings, managed and command-line settings. `tests/python/test_a_settings_file_switch_asks_the_person.py`: 50 cases, 30 of them fail on the 0.322.5 code. Prior: 0.322.5 -- **A diamonds file that cannot be read does not open the gates** (PATCH; 2026-10-12). `.claude/diamonds/active.yml` says what may be built. The build gate decided whether discovery was engaged by reading it behind handlers that caught `ValueError`, and a YAML error is not one: a file that did not parse crashed the check, the crash's exit status read as "not engaged", and an edit of product code was allowed with nothing said. Replayed on 0.322.4 in a project with diamonds and no written purpose: refused while the file was readable; allowed once it held git conflict markers, was invalid YAML, was a list, or was empty. With a purpose written the edit was refused in every state, for the wrong stated reason. A merge conflict is enough to get there. NOW: `_hook_input.py --discovery-state` answers 4 for a diamonds file that is there and cannot be read, and `--diamonds-unreadable-why` says why; `discovery-gate.sh` and `exposure-gate.sh` refuse with that reason, `brownfield-gate.sh` stands aside, and `preflight.sh` tells the agent at the prompt. An emptied file counts only where `diamond-rulings.json` shows the project had diamonds. A `purpose.yml` that does not parse no longer crashes the check. ALSO: `vercel --prod` now reaches the release checker; the hook's word filter, which runs before the checker, had no word for it, so a production deploy by that command was never judged (found while replaying the release gate for this fix). HOW IT CAME UP: an unsolicited one-line email named `_hook_input.py:530`; the line is real, the email's description of it (a hidden "connection drop") is not, since the file has no network code. NOT SHOWN: whether the agent can make the diamonds file unreadable through its own tools (shell writes to it are refused; the scale lock judges Edit and Write, and its handling of an unparseable result was not replayed); anything on Cursor or Codex. `tests/python/test_an_unreadable_diamonds_file_does_not_open_the_gates.py`: 52 cases, 22 of them fail on the 0.322.4 code. Prior: 0.322.4 -- **A hook's Python imports nothing from the project** (PATCH; 2026-10-12). A hole in every released version, found by listing every place a hook starts an interpreter after a blind reader showed 0.322.3's "a hook never runs a script from the project" was false at one site. THE HOLE: hooks run inline Python (`python3 -c`, `python3 -`) with the project as the working directory, and Python puts that directory first on its import path, so `import json` loaded `./json.py` when the project had one. Replayed on 0.322.3 with the plugin root SET, as Claude Code runs the hooks: 19 of the 56 registered hook entries imported a planted `json.py`, `yaml.py` or `re.py` (preflight on every prompt, the gate on every write, the turn-end hook, session start). A repository could have its own code run by the hooks with nothing in its settings to show for it. Claude Code's folder-trust question comes first, and a trusted repository could already run code through its own hook settings; this path was invisible there. THE FIX: `scripts/_hook_prelude.sh`, which every hook sources on line 2, exports `PYTHONSAFEPATH=1` (Python 3.11 and later) and defines `python3`, `python` and `_mycelium_py`, which hand inline code to the new `scripts/_safe_c.py`; a Python file gets its own folder on the path in place of the working directory, on every version. Call sites are unchanged, except four that start an interpreter by path or variable (one in `_python.sh`, one in `preflight.sh`, two in `_hook_fire_log.sh`). ALSO: the two sites a round 3 reader and the same audit found (`session-start.sh`, `stop-check.sh`) that put the project's `scripts` folder on the import path when `CLAUDE_PLUGIN_ROOT` is unset now use the hook's own folder; on 0.322.3 a planted `scripts/scale_locks.py` ran at session start. NOT SHOWN: that an honest project's own `types.py` or `json.py` changes what any gate decides; tested on eight gates and the build gate's two decisions, every decision unchanged, so the first version of this note's author claim to the maintainer that such a file "breaks honest projects" is withdrawn. Not run on Cursor, Codex or a Python older than the one on this machine and in CI; the launcher path is tested with `PYTHONSAFEPATH` unset. `tests/python/test_hooks_import_nothing_from_the_project.py`: 76 cases, 26 of them fail on the 0.322.3 hooks (the launcher is a new file, so its own tests pass beside the old hooks too); four of the 76 run the launcher in-process, added after CI's per-file coverage floor read it as untested. Prior: 0.322.3 -- **What the second blind read found: the secret scan covers `.claude/`, hooks run only their own scripts, a session start counts once, the opencode scaffold leaves your skills alone** (PATCH; 2026-10-12). Three new readers compared the pages of 0.322.2 with its code; none was clean, and after checking they had 15, 9 and 10 counted findings, six of them defects in behaviour and five of them sentences that 0.321.1 and 0.322.2 had put in wrongly. (1) THE SECRET SCAN COVERS `.claude/` (maintainer: "Scan .claude/ too"): `gate.sh` skipped every target under `.claude/`, so a key written into a canvas file, the decision log or memory, all committed, was never scanned; now only `.claude/state/` is skipped. A file outside the project is still not scanned. The scan has no override, so a note that quotes something key-shaped must be reworded. (2) A HOOK NEVER RUNS A SCRIPT FROM THE PROJECT: with no `CLAUDE_PLUGIN_ROOT` (Cursor, Codex) a hook fell back to `$PROJECT_DIR/.claude/scripts/` and `.claude/hooks/`, the old copied-in layout, 41 lines in 12 files, so a repository carrying a file by the right name had it run; a test that plants one shows `gate.sh` ran a planted `preflight.sh` and `session-start.sh` ran two planted checks on 0.322.2. Helpers now resolve under `_MYCELIUM_ROOT`, the folder above the running hook. Not run on Cursor or Codex. (3) ONE SESSION START COUNTS ONCE: `session-start.sh` runs twice per start on Claude Code (`--fast`, `--async`) and both passes incremented each open `*.count.json`, so a ten-session test reported done after five; the background pass now only reads. (4) THE OPENCODE SCAFFOLD LEAVES WHAT IS NOT ITS OWN (maintainer: "Never overwrite, never unasked"): `provision-skills.sh` copied over an existing `.claude/skills/` and rewrote paths in every file there; it now marks the folders it copies, replaces only marked ones, skips and names the rest, and rewrites only what it copied. The starter `opencode.json` asks before any skill that is not Mycelium's, and `/mycelium:setup` writes no scaffold in a non-interactive run unless opencode support was asked for by name. (5) TEXT: the end-of-turn count no longer says "this session" for every row the log holds; the failed-command prompt no longer cites a `CLAUDE.md` section the plugin does not ship; `PRIVACY.md` corrected where 0.322.2 was wrong (opencode "two things only", "nothing leaves your machine", what `diamond-rulings.json` stores, "adds one") and extended (scan scope, `conditional-snoozes-said`, the shell guard's index, `nudge-seen.jsonl` never trimmed, `install-runtime-hooks.sh` creating a state folder, the file listing at session start, `/mycelium:migrate-from-legacy` downloading); the system card lists what the release gate reads as a release and drops a `.claude/.gitignore` it never wrote; `README.md` and `docs/get-started.md` carry three sentences in the maintainer's wording, and the README sentence about the scope hold is removed because nothing the plugin ships switches that hold on (maintainer: "Make it real"; it returns when the hold is wired). Tests: `test_the_secret_scan_covers_dot_claude.py` (6), `test_hooks_run_only_their_own_scripts.py` (7), `test_a_session_start_counts_once.py` (5), `test_opencode_scaffold_leaves_your_skills_alone.py` (8). Prior: 0.322.2 -- **The pages a newcomer reads say what the plugin does; a scale-lock override is kept in git** (PATCH; 2026-10-12). Text corrections, plus one fix found while writing them. A blind read of 0.321.0 by three readers compared `README.md`, `PRIVACY.md`, `docs/get-started.md` and `docs/ai-system-card.md` with the code; 0.321.1 answered its two safeguard findings and three README sentences, and this release answers the rest, each checked again against 0.322.1. `PRIVACY.md`: opencode does not run the hooks (it runs a two-check plugin); the hooks read every tool call and the whole text of every shell command, and a hook reads the session transcript at the end of every turn; session start increments open `*.count.json` counters, which are committed files, and reads git `user.name`, `user.email` and the origin address in memory; `/mycelium:setup` probes for opencode and can write `opencode.json` and `.opencode/` at the project root; twelve state files that had no line are listed, among them `session-checks.json` (the full text of a session's reminders); `exposure-uses.jsonl` is named as the one log that keeps part of a command by default; `MYCELIUM_CROSS_REPO_WATCH` reads commit bodies, not only subjects; and "collects nothing" now says nothing leaves the machine while logs are kept locally. `docs/environment.md` said "every variable in one place" and named 9 of the 28 `MYCELIUM_*` names the plugin tree uses; it now names all 28, and says which three loosen a stop (`MYCELIUM_GUARD_STATE_EDIT`, `MYCELIUM_NEXT_ACTION_CHECK`, `MYCELIUM_TODAY`). `docs/ai-system-card.md`: the agent's rules arrive through the session-start hook, not a `CLAUDE.md`; advisories mute after seven days, not seven sessions; `gate.sh` logs two of its five refusals in its own log and all five in the denial ledger; the denial ledger is trimmed; the secret scan reads shell commands as well as writes. `README.md` and `docs/get-started.md`: two sentences in the maintainer's wording (a repo is asked about existing code only from a dozen source files; the first run writes four files, not two). New `tests/python/test_newcomer_pages_name_what_runs.py` fails when a `MYCELIUM_*` name or a `.claude/state/` file the plugin uses has no line on its page (3 of its 4 tests fail on the 0.322.1 pages); it checks that a name is present, not that what is said about it is true. THE FIX: `scale-lock-ack`, the person's own override of a scale lock, was the one decision file the state folder's ignore file did not keep in git, so a fresh clone had the lock closed again with no record (maintainer, shown it: "not intentional to my knowledge. Apply best practices."). `scripts/state-gitignore.txt` keeps it now. An ignore file that exists is never rewritten, so `session-start.sh` says `DECISION FILE NOT IN GIT` when any of the five decision files exists and is ignored by that folder's own ignore file, with the line to add (`_state_dir.py --ignored-decisions`, `git check-ignore`, read-only); a rule from elsewhere, such as a root `.gitignore` that leaves out `.claude/`, is the person's choice and is not reported. `tests/python/test_decision_files_stay_in_git.py` (13). Prior: 0.322.1 -- **A gate that cannot run refuses the call, in a project that uses Mycelium; session start keeps what a person wrote** (PATCH; 2026-10-12). Claude Code lets a tool call through when a hook cannot start, times out or exits with an unexpected status, so every Mycelium gate let the write through in those cases. The nine gates that can refuse now carry `"onFailure": "block"` (Claude Code 2.1.295 or later), behind a check in the command itself that leaves at once in a project without `.claude/canvas/` or `.claude/diamonds/`, so a hook that cannot start refuses only where Mycelium is in use. A refusal that could not be printed because python3 cannot run is now a refusal too. Session start no longer overwrites hand-written content inside a diamond's stored closing path: it leaves that block alone and says where to move the content. On Windows without Git Bash the commands cannot run and writes are refused in every project. Prior: 0.322.0 -- **A project that deploys is asked whether something is already live** (MINOR; 2026-10-11). The release gate judges a deploy the agent runs, against exposure records, so a product somebody put live by hand sat outside the Security and Privacy checks and nothing named it. Now, when a project uses Mycelium, its repository shows it deploys (a host's config file, a workflow that deploys) and no diamond records who it reaches, one line at session start asks whether something is already in front of real people and offers to record it; `/mycelium:adopt` asks the same when Mycelium is brought into existing code. The sign shows the project can deploy, not that it is live, so it is a question. It stops once answered, and nothing about it is read by any gate. Prior: 0.321.1 -- **Two stops that could be walked around** (PATCH; 2026-10-11). Both found by a blind read of 0.321.0. (1) A shell write through a variable reached a file that switches a stop off, and nobody was asked: the hook that asks can only read a write target it can see. The files that switch a stop off are now compared before and after every shell command, also one that fails, and a change the person was not asked about is put back and reported to them. (2) The build gate counted an edit as building for the Edit tools only; a whole-file write over existing product code, a notebook edit and a shell edit passed. A write to an existing product file is now judged as an edit whatever tool makes it. Three README sentences the same read found untrue are corrected in the maintainer's wording (nothing is held before `/mycelium:start`; the agent can write an off-switch file only if you agree; not everything else is a warning). Nothing here adds a way past a stop. Prior: 0.321.0 -- **The harms check is named at release, as advice that never blocks** (MINOR; 2026-10-11). `/mycelium:harms-check` asks who a product could harm when it works as designed, and nothing that runs named it: in 175 end-to-end runs it was mentioned in 1, against 33 for the privacy check, whose record the release gate requires. Now, when a current exposure record has no harms check recorded on it, the release path says so in one advisory line (as context on an allowed release, in `scale_locks.py --exposure-state` and `--exposures`, and in the gate's refusal beside the required checks), and the verdict is recorded on the exposure as `harms_check: {on, verdict, note}`. No verdict, missing or Happier-negative, changes what is allowed or refused. Prior: 0.320.0 -- **A leaf bakeoff is decided by its tests, not by a gap in ICE scores** (MINOR; 2026-10-11). Until now a 20% gap in ICE totals decided whether competing ideas for one opportunity were compared and which one won; no source has that rule. Leaves are now compared whenever two or more each have an untested riskiest assumption, the assumption-test verdicts decide, and the ICE total only orders which assumption is tested first. The `bakeoff_delta` threshold is retired with its calibration rule (a canvas that still carries it validates and gets one WARN). The Noise Check in `/mycelium:ice-score` no longer gives a "1 point" number it had no source for. This changes which leaves an agent compares and which one it advances. Prior: 0.319.2 -- **The work-recording check counts releases from version tags** (PATCH; 2026-10-11). `check_cycle_recording.py` counted minor releases by parsing commit subjects, in repositories that carry a version tag per release. It now reads the release repository's version tags (`v1.4.0` or `1.4.0`) when it has any, and commit subjects only when it has none; the output says which it read. A repository with tags and no new minor tag since the last cycle is a measured zero, not "could not measure". `--release-pattern` still forces the subject scan. Prior: 0.319.1 -- **The suite cannot write into the repository of whoever runs it; the secret scan refuses when it cannot run** (PATCH; 2026-10-11). Run from a git worktree, the pre-push hook's tests acted on the repository being pushed: git exports `GIT_DIR` to hooks there, so fixture `git init`, `config` and `commit` calls wrote `core.bare = true`, a dummy author and fourteen commits into the real repository. Every place that runs the suite now clears the variables that redirect git, fixture repositories are checked before use, and a test fails any bare `git init` in a test file. Separately, the secret scan treated a grep that could not run as "no match"; it now refuses the write and says the scan failed. The scan has no override, by design. Also: `scripts/gates.sh` wrote its verdict through `tee /dev/stderr`, which on Linux empties the log the script is redirected to; it is now two plain writes. If you installed the pre-push hook, copy it again. Prior: 0.319.0 -- **ICE as Gilad defines it: multiplied, with his Confidence Meter, and no threshold on the total** (MINOR; 2026-10-11). The literature has two versions of ICE and Mycelium had matched neither: it averaged, as Ellis does, while describing Gilad's meter with values that are in no version of it, and kept a threshold of 100 on the total that no source has. On the founder's choice `/mycelium:ice-score` now computes Impact x Confidence x Ease, each 0-10, with Impact against a named metric, Ease as the effort to build in full, and Confidence summed from evidence with the Confidence Meter's own weights and caps. The total is a hint for comparing ideas; a low rank parks a leaf and never kills it; `ice_advance` is retired. `check_ice_aggregate.py` turned with the rule and still never rewrites a canvas: run it once with `--write-baseline` after upgrading. Rankings change; old scores are left as they are. Prior: 0.318.4 -- **The README, the get-started page and the menu say what the brief switches on** (PATCH; 2026-10-11). Three README passages that said nothing is held after the four questions are rewritten in the founder's words; get-started no longer says "Building is open whichever you pick"; and the menu after the brief follows the framework's own rules for choices: the hold is said first, one option is always recommended, three are listed, "build a prototype to learn" is one of them, and the friction-log line invokes `/mycelium:friction-log`. No behaviour changes. Prior: 0.318.3 -- **Two safeguards that did not hold** (PATCH; 2026-10-11). Removing `.claude/canvas` and `.claude/diamonds`, which switches every hook off, is now judged by `guard-state-gate.sh` as 0.318.0 said it was: the hook's cheap exit had let the removal through before the helper saw it, in every permission mode. The secret scan in `gate.sh` uses POSIX classes: under the BSD grep on macOS its bracket expressions read `\s` as the letter s and `\x27` as x, 2 and 7, so a credential was caught or passed by its letters. A database address with no password is no longer refused as a secret. Thirty-five new tests, all but one run through the hooks themselves; sixteen of them fail on 0.318.2 under the grep macOS ships. Prior: 0.318.2 -- **Two notes and a welcome say what the code does** (PATCH; 2026-10-11). The ICE note and the confidence-thresholds comment no longer say Gilad's confidence penalty is preserved: nothing computes a weighting, the average carries no penalty, and the note now says what stands in its place and tells the agent to report Confidence beside every score. `/gist-plan` scores Confidence 1-10 like `/ice-score`. The start welcome says, before the first question, that building the product waits for a delivery diamond once the brief exists, and how to lift that. No behaviour changes. Prior: 0.318.1 -- **Four false readings from one dogfood session** (PATCH; 2026-10-10). A premortem's task mention is no longer a closing input; a `{id, ref}` pointer is no longer a duplicate id; a variable before `..` no longer normalises into a project path; and the diamonds-file guard no longer refuses a read that writes elsewhere through a variable. Prior: 0.318.0 -- **Nothing outside a Mycelium project; inside one, logs listed, trimmed, kept out of git, and holding no commands** (MINOR; 2026-10-10). From Anthropic's plugin directory review of v0.317.4 and the founder's rulings on it: in a project with no .claude/canvas or .claude/diamonds every hook exits at once, with no gate, output or log (a fresh repo is no longer gated before /mycelium:start); in a Mycelium project the reflexion log keeps the time, exit code and program name, never a failed command or its output unless the user opts in (masked), activity logs keep 90 days (MYCELIUM_LOG_RETENTION_DAYS), and every hook writes `.claude/state`'s ignore file on exit when it is missing; the release gate allows a project with no diamonds file before it needs PyYAML; PRIVACY.md lists every log, what a line holds and how long it is kept. Prior: 0.317.5 -- **A scored instrument is not "no expiry" either** (PATCH; 2026-10-08). check_instrument_contract skips scored as well as void instruments in its expiry step. Prior: 0.317.4 -- **A void instrument is not a problem** (PATCH; 2026-10-08). check_instrument_contract no longer reports void instruments as NO EXPIRY or as undersized/oversized. Prior: 0.317.3 -- **A review marker under `what` no longer supersedes the purpose** (PATCH; 2026-10-08). The purpose intent hash also drops the framework's reviewed markers (handles_checked, reply_not_owed, stale_prose_reviewed, checked_skills, checked_against); hashes stamped under v0.141.0 stay accepted. Prior: 0.317.2 -- **define-done: at the learning scales, "what changes" names the decision** (PATCH; 2026-10-08). Step 1 gains an L0-L3 branch (the change is what the owner can now decide, so the outcome names the decision the answer unlocks) and a rule that a problem is named in words, never by an id alone. Prior: 0.317.1 -- **`jtbd-map` uses Ulwick's opportunity score** (PATCH; 2026-10-08). The 2026-09-20 formula correction missed this second copy; step 5 now points to user-needs-map's definition. Prior: 0.317.0 -- **Other people's language is read for meaning, not for words** (MINOR; 2026-10-08). From a consumer project: skills that read interviews, posts, reviews or tickets as evidence matched on words, so they under-counted by construction and read a search's silence as an absence (dogfood measurement: a phrase filter caught 2 of 25 posts found by reading for meaning). New engine/reading-for-meaning.md, pointers in ten skills at the step where they read language, and validator Check 56 for the wiring. Prior: 0.316.3, in which preflight no longer waits forever when an agent runs it.**Preflight no longer waits forever when an agent runs it** (PATCH; 2026-10-07). A shell-tool command containing a heredoc gets a stdin socket that never reaches EOF, and preflight read its payload with $(cat), so an agent re-running it as gate.sh instructs could hang (35 minutes observed). The read is now bounded to 3 s, reproduced and tested both ways. Prior: 0.316.2, in which the plugin's own README says what it connects to.**The plugin's own README says what it connects to** (PATCH; 2026-10-07). The plugin README linked to a PRIVACY.md that installed users do not get; it now lists the one automatic call (ci-signal to GitHub via gh) and every user-started network action, and PRIVACY.md no longer claims Mycelium reads no credential while metrics-pull uses the credentials you configured. Prior: 0.316.1, in which skills stop pointing at things an installed plugin does not have.**Skills stop pointing at things an installed plugin does not have** (PATCH; 2026-10-07). From a /doctor prompt-audit run, each finding checked against the source: 38 skill pointers to CLAUDE.md sections now name the operating contract; a 22-skill preflight line lost stale line numbers and a dogfood-only reference; diamond-assess counts gates at run time (it said 13, the engine has 15); interview no longer recommends npx degit or phase moves; three links that left the plugin folder are GitHub URLs. Prior: 0.316.0 a refusal another extension overrules is said.**A refusal another extension overrules is said** (MINOR; 2026-10-07). Claude Code 2.1.287 shipped Mods, and a mod can approve a call a plugin PreToolUse hook refused, which every Mycelium gate is; the fire logs still said the gate held. Each refusal now writes its tool_use_id to a denial ledger, and a new PostToolUse hook (gate-override-check.sh) tells the person and the agent when a refused call ran anyway. Proven against a real test mod under claude -p. Prior: 0.315.0 a scale-lock block says what was missing.**A scale-lock block says what was missing** (MINOR; 2026-10-05). The scale-lock gate logged every refusal as `blocked` and nothing else: 110 blocks across 62 E2E runs, none saying whether a missing upstream record (the entry lock) or a diamond's own decision gates stopped the builder. Each refusal now carries its kinds (`entry_lock`, `decision_gates`, `rewritten_decision`, ...) as the block log's detail, so where builders are stopped, and by what, can be measured. Prior: 0.314.1 correction to the v0.314.0 notes.**Correction to the v0.314.0 notes** (PATCH; 2026-10-05). v0.314.0 cited two dogfood `scenario:` keys as leaves following ost-builder step 6; both are `dogfood_result.scenario`, eval-fixture paths unrelated to the scenario link. The changelog entry and the check's docstring are corrected; the defect and its fix stand, with no behaviour change. Prior: 0.314.0 a scenario names the opportunities it illustrates.**A scenario names the opportunities it illustrates** (MINOR; 2026-10-05). ost-builder told each solution to name its scenarios and asked whether every leaf opportunity has one, but no schema declared either link and nothing read one. Scenarios now carry the link in `addresses_opportunities` (declared); a solution's scenarios are derived from its opportunity; validate_canvas reports dangling ids and counts open opportunities with solutions that no scenario names. Prior: 0.313.1 a parked diamond still holds its slot.**A parked diamond still holds its slot** (PATCH; 2026-10-05). 0.312.1 taught the closing path about parks, but the slot checks used is_open, which leaves parked out: a parked L3 read as "no L3 works it", so the next item offered a second L3 on the same target, and one-L2-per-outcome, one-L3-per-target and the re-target rule all ignored a park. They now read holds_slot (open or parked). Prior: 0.313.0 a choice is written when it is made.**A choice is written when it is made** (MINOR; 2026-10-05). An L2's target and an L3's front runner are choices that a gated decision later records; when the decision was held for evidence, the skills let the choice be withheld as if it were the decision, so the next item asked every session for a comparison already made. ost-builder and diamond-progress now say the choice is written when made, and the next item names a ruled L2 whose choice was never written. Prior: 0.312.3 the icon's corners are transparent.**The icon's corners are transparent** (PATCH; 2026-10-04). The plugin icon had opaque white outside its rounded square, which showed as white corners on any dark surface; the corners are now transparent and the curved edge keeps its anti-aliasing. Prior: 0.312.2 a closed diamond is not derived either.**A closed diamond is not derived either** (PATCH; 2026-10-04). 0.312.1 taught the closing-path controller about parked diamonds only; a diamond archived, completed, killed or retargeted in place was still given a closing path, and a verdict landing on it became the session's next item, "run /mycelium:diamond-progress" on a stopped diamond. The controller and the next-item picker now read the same closed set scale_locks uses. Prior: 0.312.1 a parked diamond is not an unnoticed gap.**A parked diamond is not an unnoticed gap** (PATCH; 2026-10-04). The closing-path controller reported a parked diamond as "NOTHING ON RECORD moves a pending gate", so session start kept flagging a deliberate pause; it now prints when it was parked and how many resume conditions it has, and derives nothing for it. Prior: 0.312.0 a quieted advisory speaks again when its count rises.**A quieted advisory speaks again when its count rises** (MINOR; 2026-10-04). The advisory ledger records the count an advisory was muted or ruled at, and shows it once, with its own text, when the count rises past that; an advisory its own check forbids clearing mutes without asking for a ruling. Prior: 0.311.1 a private way to report a vulnerability.**A private way to report a vulnerability** (PATCH; 2026-10-04). SECURITY.md names the route (GitHub private vulnerability reporting, now on) and what a solo maintainer can promise: acknowledgement within 7 days, serious issues fixed or mitigated within 30, latest release only; the system card's contact section points to it. Prior: 0.311.0 a framework turn's Next: line cites its trigger.**A framework turn's Next: line cites its trigger** (MINOR; 2026-10-03). next-action-check.sh now blocks, once, a Next: line with no (per: <source>), giving contract rule 4 a mechanism after two audits measured it at 3 sessions in 12 as prose; and it now checks turns started by a /mycelium: slash command the person typed, which it never saw before. Prior: 0.310.20 context-surface.md is stamped against the hooks too.**context-surface.md is stamped against the hooks too** (PATCH; 2026-10-03). The hook-digest check that keeps the system card honest now also holds docs/context-surface.md, the second document that describes the hook layer; it missed the contract's move in 0.310.16 because nothing stamped it. Reading it against the hooks found four blocking or asking hooks it did not name, and hooks/README.md, the full table, missing four. Prior: 0.310.19 the docs name the contract's real injector and drop a stopped pilot.**The docs name the contract's real injector and drop a stopped pilot** (PATCH; 2026-10-03). docs/context-surface.md said session-start.sh injects the operating contract; since 0.310.16 contract-part.sh does, in four parts. The system card named the Juniors.dev pilot, stopped on 2026-08-14, as the next test, and gave the fifth audit as the last. Prior: 0.310.18 hook hygiene from the plugins-reference review.**Hook hygiene from the plugins-reference review** (PATCH; 2026-10-03). Nine handlers get explicit timeouts, shell-safety-guard its own status line, ping is kept from model invocation, and the carried-over reflexion warning, unreachable after session-start.sh's exit since v0.64.0, finally reaches the session. Prior: 0.310.17 the tests follow the contract to its new home.**The tests follow the contract to its new home** (PATCH; 2026-10-03). Five tests and Check 47's fixtures assumed session-start.sh carried the contract; they now check the contract-part.sh handlers and the cap. Prior: 0.310.16 the operating contract reaches the model whole.**The operating contract reaches the model whole** (PATCH; plugins-reference review 2026-10-03, founder go). Claude Code caps a hook's additionalContext at 10,000 characters and shows a 2,000-character preview of anything longer; the contract (about 22,000) rode in one string, so sessions got its first section. It now arrives in four parts that each fit, with the real plugin path in place of ${CLAUDE_PLUGIN_ROOT}. Prior: 0.310.15 Mycelium has an icon.**Mycelium has an icon** (PATCH; founder approved 2026-10-03). A square PNG at .claude-plugin/icon.png, named by plugin.json's icon field, for the Claude directory listing. Prior: 0.310.14 update instructions that work.**Update instructions that work** (PATCH; plugins-reference review, 2026-10-03). The docs said plugin auto-update is on by default and gave a command that only refreshes the catalog; for this marketplace auto-update is off by default. Prior: 0.310.13 what Mycelium runs and connects to, stated truthfully.**What Mycelium runs and connects to, stated truthfully** (PATCH; Claude directory review, 2026-10-03). The link checker no longer reads a GitHub token from the environment; PRIVACY.md, the system card, hooks/README.md, environment.md and the plugin README now say what the code does. Prior: 0.310.12 hook commands quote the plugin path.**Hook commands quote the plugin path** (PATCH; `claude plugin validate` warnings, 2026-10-03). Every hook command in the Claude Code, Codex and Cursor manifests used its plugin path without quotes, so an install path with a space split the command; all are quoted now and validate passes with no warnings. Prior: 0.310.11 leaf-lifecycle.md names its steps by decision, not by retired phase.**leaf-lifecycle.md names its steps by decision, not by retired phase** (PATCH; docs north-star reference cleanup, 2026-10-03). Its nine step headings and the L4 note used Discover/Define/Develop/Deliver, retired in v0.306.0; each now names the decision it sits beside. Prior: 0.310.10 the README's hooks paragraph shows what holds work back today.**The README's hooks paragraph shows what holds work back today** (PATCH; founder ruling 2026-10-03). It said four hooks could hold work back and that a bug fix never meets the discovery stop; both stopped being true. It now says what each kind of stop holds, without counts. Prior: 0.310.9 the evaluator pages say what Mycelium does today.**The evaluator pages say what Mycelium does today** (PATCH; docs north-star item 8, 2026-10-03). docs/evaluate.md and docs/usage-modes.md, last touched in May, are corrected claim by claim against the code; /mycelium:canvas-sync now stages .claude/diamonds/. Prior: 0.310.8 history of the retired phase loop no longer reads as the current model.**History of the retired phase loop no longer reads as the current model** (PATCH; warm-reader finding 2026-10-02, roadmap worksheets item 5b). docs/philosophy.md marks its four-phase history paragraph as a history aside (wording unchanged); docs/glossary.md drops the same history from the Diamond entry, which the Phase entry already marks retired. Prior: 0.310.7 the discovery page reworded where readers tripped, and it now shows a stop.**The discovery page reworded where readers tripped, and it now shows a stop** (PATCH; founder ruling 2026-10-02/03, roadmap DL-1399 to DL-1403). docs/mental-model.md: sentences that six rounds of simulated readers tripped on are reworded, and two short paragraphs say what a stop looks like and how it works on a team. Prior: 0.310.6 the file-viewer story says what actually happened.**The file-viewer story says what actually happened** (PATCH; founder ruling 2026-10-02, roadmap DL-1392). The README, the evaluate page and the receipt stop saying the file viewer was killed by asking real people or 'with evidence': per the project's own 2026-04-09 log it was stopped on six simulated users, which Mycelium graded as speculation, and the real interviews it listed next were never run. Prior: 0.310.5 the README opens with what Mycelium won't do.**The README opens with what Mycelium won't do** (PATCH; founder's words, 2026-10-02). README.md's first line becomes "Mycelium won't make your idea good. It keeps you and your agent honest about whether it is, from first idea to market.", matching the scope of the new GitHub About text, and the Start section links docs/get-started.md, which the README never linked. Prior: 0.310.4 the Definition of Done rationale is a page, not a design file.**The Definition of Done rationale is a page, not a design file** (PATCH; docs north star, founder ruling 2026-10-02). docs/design/definition-of-done.md moves to docs/definition-of-done.md as an explanation page with an audience marker; the four framework files that cite it (diamond-rules, define-done, canvas-health, a session-start comment) follow, and canvas-health stops saying a diamond 'reaches Deliver'. docs/design/ is empty and gone. Prior: 0.310.3 fewer pages, each with a reason to exist.**Fewer pages, each with a reason to exist** (PATCH; docs north star, roadmap DL-1386, founder ruling 2026-10-02). docs/faq.md and docs/receipts/archive.md are removed, the three receipts indexes become docs/receipts/index.md, docs/skills/by-category.md folds into the skills index (Check 6b and its sync entry go with it), and two unreferenced maintainer design plans move from docs/design/ to .claude/evals/design/. Every FAQ answer already had a home or gains one line. Prior: 0.310.2 reference pages say decisions, and two orphan pages get a way in.**Reference pages say decisions, and two orphan pages get a way in** (PATCH; docs north star, roadmap DL-1386). context-surface.md, the skills index and the agent operating contract stop describing a diamond by its retired phase: where a diamond is is read from its recorded decisions, and guardrails load by scale. The glossary gains a purpose-stance entry linking docs/purpose-stance.md, and the system card links docs/threat-model.md; neither page had a link from anywhere. Prior: 0.310.1 get started leads to running it on a project.**Get started leads to running it on a project** (PATCH; docs north star, roadmap DL-1386/DL-1387). docs/get-started.md is rebuilt by the Core Model worksheet: its goal is running Mycelium on a real project, with the four questions as the milestone on the way; it says what the brief writes and where, what to do after the menu, how to judge it over three projects, what it costs, and how to remove it, and stops linking the stale FAQ and evaluate pages. Three skills stop writing the retired phase on a new diamond (interview, launch-tier) or naming it (ost-builder). Prior: 0.310.0 the work-recording check reads the releases it counts.**The work-recording check reads the releases it counts** (MINOR; dogfood DL-1375). check_cycle_recording.py counts unprefixed release subjects ("0.310.0: ...") at the start of a subject, counts each version once, and reads the release repo from `thresholds.yml#cycle_recording_arc.release_repo`, so a consumer whose releases ship elsewhere is measured at session start; a configured path missing on this machine is a `release-repo-missing` status the hook relays. A thresholds.yml with no `thresholds` table is a calibration WARN instead of silence. The release arc is no longer reported as due for calibration: no rule exists for it, so its mapping to effort_accuracy is removed. Measured on the dogfood repo: the check read 1 release where 111 had shipped. Prior: 0.309.6 why Mycelium is opinionated, for the reader deciding.**Why Mycelium is opinionated, for the reader deciding** (PATCH; stage 6, DL-1369). docs/philosophy.md is rewritten for the evaluator asking why it is so strict: five reasons, each with one plain receipt, the multi-team scope in four sentences, and next steps; drafted by the agent from the founder's edit, voice-gated, and approved by him. The mechanics it carried (the framework loop, build mode, the single-team findings) move to architecture.md. Prior: 0.309.5 the reference docs and the README say what the code does.**The reference docs and the README say what the code does** (PATCH; stage 6, DL-1369). The README no longer says a weekend project skips layers (false since v0.247.0) and its footer names the page it links; glossary.md defines decisions, modes, positions and exposure records and retires Phase; theories.md places Four Risks and Cynefin at their decisions and credits Rother and dual-track for the loop, with what is Mycelium's own said as such; architecture.md loads domain context by the work at hand. Prior: 0.309.4 what discovery before the build gives you.**What discovery before the build gives you** (PATCH; stage 6, DL-1369). docs/mental-model.md is rewritten for the reader who has read the README and is not convinced yet: the measured case (randomised trials: the wrong project is stopped weeks sooner, not more often) and documented failure stories, drafted by the agent from three research sweeps and rewritten by the founder; the docs that point at it, architecture.md's diamond description and wayfinding's skipped-scale example are corrected. Prior: 0.309.3 every skill and rule says decisions.**Every skill and rule says decisions** (PATCH; stage 5d-3c, DL-1372). The remaining skills, engine and harness files, the journey map and the stop-check message speak in decisions and two modes; xai-check named the XAI gate at moves the code never asked it at; no verdict changes. Prior: 0.309.2 the gates and the diamond rules say decisions.**The gates and the diamond rules say decisions** (PATCH; stage 5d-3b, DL-1372). theory-gates.md and diamond-rules.md speak in decisions and two modes; the per-scale gate tables have one column per decision, and they and every gate's Applies-to line are now compared with the code (two Applies-to lines had said L2-L4 where the code requires L2-L5); no verdict changes. Prior: 0.309.1 a recorded decision stays recorded.**A recorded decision stays recorded** (PATCH; DL-1374, enforcing DL-1373). The scale-lock gate refuses a write that removes a recorded decision or changes its name or date, wherever the diamond now sits; notes, gates and rulings stay editable, a missing date may be filled in, and appending still passes. Prior: 0.309.0 a diamond moves by recording decisions, and is drawn as them.**A diamond moves by recording decisions, and is drawn as them** (MINOR; stage 5d-3a, DL-1372 V4, DL-1373). /diamond-progress speaks in decisions, names how a loop iterates (append another `start_experiment` or `commit_to_build`, never remove one) and no longer asks for `progression_history`; /diamond-render calls the new `render_diamonds.py`, which draws each diamond as its decisions in order, grouped by mode; no verdict changes. Prior: 0.308.2 session-start checks read this project, not copies of others.**Session-start checks read this project, not copies of others** (PATCH). The stale-prose and source-authenticity checks skip project snapshots kept under `.claude/` (a directory with its own `canvas/` or `.claude/`), and the second reads the project's own handles once per scan; the background tier no longer cites a timeout that does not apply to it. Prior: 0.308.1 what the agent reads is keyed by decision.**What the agent reads is keyed by decision** (PATCH; stage 5d-2, DL-1372 V2). confidence-thresholds.yml's approvals, thresholds and evidence, and theory-gates' Transition Matrix, are keyed by decision; the drift check compares the matrix with `scale_locks.DECISIONS`; no verdict changes. Prior: 0.308.0 Mycelium says where a diamond is by its decisions.**Mycelium says where a diamond is by its decisions** (MINOR; stage 5d-1, DL-1372). Messages and next items speak in decisions and the two modes ("target set", "committed to build", "released"; "record `release`" instead of "move to Deliver"); no verdict changes on the stage's frozen corpus. Prior: 0.307.9 a repair that cannot see a diamond's exposures is refused for it.**A repair that cannot see a diamond's exposures is refused for it** (PATCH, safety; DL-1371). Closes the residual 0.307.7 shipped with: the rulings record always says whether a delivering diamond has exposures, and a repair whose last good state cannot show them is refused for that diamond, with the remedy. Prior: 0.307.8 controls that test their rule.**Controls that test their rule** (PATCH; DL-1370 batch 4). Five controls the audit found passing for the wrong reason are rewritten with explicit records and checked against planted defects; a move's `progression_history` requirement, which could not fire since v0.306.0, is removed. Prior: 0.307.7 lifecycle.**Lifecycle** (PATCH, safety; DL-1370 batch 3). An L3 ended by archiving, by killing after parking, or by removal from the file says how its learning delivery ended; an L3 inheriting its L2's target closes when the L2 re-targets; a repair of a broken diamonds file is judged with the running exposures. Prior: 0.307.6 the build gate.**The build gate** (PATCH, safety; DL-1370 batch 2). A discovery-skip-ack lifts the cold-project gate only; an ack's scope and the declared prototypes cover every file a command writes; an L4 on a set names what it delivers, unwaivably; a diamond stamped `completed_at` without `close` carries nothing; the build refusal prints its remedy. Prior: 0.307.5 the release path's judgement.**The release path's judgement** (PATCH, safety; DL-1370 batch 1c). Closing an L5 that already delivers asks the person; a widening is judged once the L3 reaches people or may (a current or started exposure), not only after `release`; the Develop trial is an exposure, recorded first (ruling a); the prompt and change lines read readiness as the release gate does. Prior: 0.307.4 shell and file-move paths to the diamonds file.**Shell and file-move paths to the diamonds file** (PATCH, safety; DL-1370 batch 1b). A shell write that launches an L5 or records personal data is reported; naming Mycelium's own writer no longer excuses another write; moving the diamonds file away is refused, through the shell or MCP. Prior: 0.307.3 the release gate's inputs.**The release gate's inputs** (PATCH, safety; DL-1370 batch 1a). A project whose diamonds have all completed is judged; more releases are recognised (a list plus any command named for a deploy/publish); a non-ISO end date no longer keeps a record current; a structured skip-ack with no ISO date lifts nothing; personal data however written asks the person. Prior: 0.307.2 a completion with no `close` is judged again.**A completion with no `close` is judged again** (PATCH, safety). A diamond written into completed_diamonds without recording `close` read as not having moved and passed no completion gate (since v0.303.0 for diamonds with decisions, v0.306.0 for all): an L3 could complete with its learning delivery never ended. It is judged as a move to complete again, and the missing decisions are named. Prior: 0.307.1 what 0.307.0 still read in the old shape.**What 0.307.0 still read in the old shape** (PATCH). The scale-occupancy report counts an L2's recorded target only, as the lock does, and judges it closed by its state or `close` decision; the build gate's message reads where a diamond is from its decisions; /diamond-render, /metrics-pull and diamond-rules stop treating the `phase` label as the record. Prior: 0.307.0 the old object and delivery shapes are no longer read.**The old object and delivery shapes are no longer read** (MINOR, BREAKING). Phase migration stage 5c-2 (DL-1367 R4, DL-1368 S4). An L2 targets only its recorded `target`, an L3's front runner is only its recorded `front_runner`, and an L3's learning delivery is only its exposure record: `learning_delivery` is not read. The migration offer now comes right after fired proposals, listing every diamond the migration would change, and a started delivery nobody migrated stays in the exposure report. Prior: 0.306.0 the phase is no longer read.**The phase is no longer read** (MINOR, BREAKING). Phase migration stage 5c-1 (DL-1368 S4). Where a diamond is comes only from the decisions it records: a diamond with only a `phase` reads as discover, and a release needs an exposure record (the phase fallback is gone). `migrate_phase.py` converts a project, now reading the recorded field, carrying a closing phase into `state`, and judging its result against where the diamonds were recorded. Prior: 0.305.0 every reader of where a diamond is reads its decisions.**Every reader of where a diamond is reads its decisions** (MINOR). Phase migration stage 5b (DL-1368). The next item, the closing path, the purpose-stance check, the stop hook and the session-start outcome check read where a diamond is through `scale_locks.phase_of` (the decision log, the recorded phase only without one); /diamond-progress records each move's decisions with their gates, an L0 records `review` instead of moving and is never offered a move, migrate_phase.py migrates an L0 recorded `complete`, and /diamond-render draws from the decisions. Prior: 0.304.0 an L2 opens under the L1 that set its outcome.**An L2 opens under the L1 that set its outcome** (MINOR). 0.301.0's L2 door paired an unmapped outcome with the first L1 whose lock held, so with two L1s it named the wrong parent (the dogfood repo, 2026-10-01). An outcome now names its L1 in `set_by`; the door opens only under it, a new L2 under another L1 is refused, and with no name and several L1s the next item asks which. Prior: 0.303.0 a diamond records its decisions, and a migration moves the phase into them.**A diamond records its decisions, and a migration moves the phase into them** (MINOR). Phase migration stage 5a (DL-1368). Where a diamond is, is read from its decision log, the recorded phase only when it has none; an L0 records state_purpose and review. `migrate_phase.py` rewrites the phase history as dated, reconstructed decisions, a learning delivery as a reconstructed exposure record, and the old L2/L3 shape as the new fields, and writes only what the scale locks read as no change. No new refusals. Prior: 0.302.0 one L2 per outcome, one L3 per target, and re-targeting closes the old L3.**One L2 per outcome, one L3 per target, and re-targeting closes the old L3** (MINOR, adds blocks). Phase migration stage 4c (DL-1367 R2, R3). A second L2 on an outcome or a second L3 on a target is refused when it opens; an L2 that re-targets closes the L3 on its old target in the same write as `retargeted`; an L3 ended by its state (killed, archived, retargeted) says how its learning delivery ended, as a completion does; L5 results join the existing L2's map. Prior: 0.301.0 an L2 opens on an outcome and an L3 on its L2's target.**An L2 opens on an outcome and an L3 on its L2's target** (MINOR). Phase migration stage 4b (DL-1367, ruling C). The doors open per outcome and per target, not on a record from a pile: /ost-builder offers both, /ice-score compares the ideas inside an L3 and opens nothing. An L2 with no target is asked to choose one by comparison; an L3 stops when its front runner fails or none of its ideas works, never on one sibling; a diamond in the old shape is asked to record the new fields. Prior: 0.300.0 an L2 targets, an L3 commits a front runner, and the L4 reads what it delivers.**An L2 targets, an L3 commits a front runner, and the L4 reads what it delivers** (MINOR). Phase migration stage 4a (DL-1367). An L2 names its outcome and a current `target`; an L3 is that target and its solutions and names a `front_runner`; the old one-opportunity and one-solution shapes are read through a translation until stage 5. The L4 lock reads the verdicts of the solution it delivers: a validated sibling no longer opens it, and a failed sibling no longer blocks it. Prior: 0.299.0 the closing path says what each gate is owed before.**The closing path says what each gate is owed before** (MINOR). Phase migration stage 3b-2. Pending gates are grouped: owed before the next move's decisions (named), the safety gates that move needs, gates only a later move needs, and gates passed with a risk, which were listed as if owed. The purpose-stance check blocks from the decision to build (ruling e), read from the decision table. Prior: 0.298.0 the gates are keyed to the decisions they guard.**The gates are keyed to the decisions they guard** (MINOR). Phase migration stage 3b-1 (DL-1366). Each level's learning loop makes five decisions (set target, start experiment, commit to build, release, close) and each gate belongs to the one it guards; a phase move makes a fixed set of them, so it needs the same gates as before, pinned cell by cell against 0.297.0. A move's history entry names its decisions. Prior: 0.297.0 the gates a diamond is born with agree with the gates its moves require.**The gates a diamond is born with agree with the gates its moves require** (MINOR). Phase migration stage 3a. An L5 is born with Privacy and Service Quality, which its moves have required since 0.292.0 (ruling f); Delivery Metrics is no longer required when an L5 closes, as the gate's own definition and 0.235.0 say; and the drift check compares every born list with the per-transition table, so the two sources cannot part again unseen. Prior: 0.296.0 an L3's learning delivery can be its exposure record.**An L3's learning delivery can be its exposure record** (MINOR). Phase migration stage 2b. Every rule on an L3's learning delivery (its fields, its end date, how it ended, a change to its audience, end date, channel or data) reads `learning_delivery` when the diamond carries it and its exposure record otherwise, so one record serves both; recording an exposure is not a start, and the messages name the record in use. Prior: 0.295.0 the release gate reads exposure records.**The release gate reads exposure records** (MINOR). Phase migration stage 2 (DL-1365). In a project that records exposures, a release needs a current record (in date, its fields filled, Security, Privacy and Service Quality passed for it, on a diamond whose chain holds): one allows it, several ask the person which, none refuses with the reasons. A project with no records yet keeps the phase check and is told to record one. Contract rule 14 says the same. Prior: 0.294.0 exposure records: who the work reaches, recorded on its diamond.**Exposure records: who the work reaches, recorded on its diamond** (MINOR). Phase migration stage 1. A diamond whose work reaches people carries `exposures[]` (audience, channel, data class, end date, consent, the gates passed for it); `scale_locks.py --exposures` reports the gaps and blocks nothing yet, and a write that adds an exposure with personal or sensitive data asks the person (ruling g). Prior: 0.293.0 the delivery skip-ack is a dated, scoped record.**The delivery skip-ack is a dated, scoped record** (MINOR). Phase migration stage 0b-3b, founder ruling DL-1364. The file's mere existence lifted the build and release gates for all work, forever, and it was gitignored. Now it lifts the build gate only for the paths it `covers`, a release only when it says `releases: true`, expires after 30 days by default, logs every use, and setup keeps it in git; an old bare file is honoured for 14 days with a warning. Prior: 0.292.0 an L5 launch asks a person; the gate table carries XAI and L5's privacy and service quality.**An L5 launch asks a person, and the gate table carries XAI and L5's Privacy and Service Quality** (MINOR, adds blocks). Phase migration stage 0b-3a. The L5 human-approval floor was prose no code read; a write that moves an L5 into deliver or complete now asks in the permission dialog, and is refused where nobody is asked. The explainability gate joins the table the phase gates read (L3-L5, only with AI components), L5 needs Privacy and Service Quality before it delivers, the drift check compares the per-transition table with the code, and an id used as a map key no longer trips the key-shape guard. Prior: 0.291.1 an override citing a recent decision is no longer read as dangling.**An override citing a recent decision is no longer read as dangling** (PATCH). The purpose-stance check found decision IDs only when a heading began with one; the dogfood log's date-first headings (`## 2026-09-24 — DL-1361: ...`) since about DL-1286 were invisible, so it reported 236 IDs and missed the newest 77, and a founder override citing DL-1363 read as dangling. Prior: 0.291.0 editing product code counts as building; an exposed pilot cannot widen unseen.**Editing product code counts as building, and an exposed pilot's record cannot widen without its gates** (MINOR, adds blocks). Phase migration stage 0b-2; the last two run-10 holes. Once discovery is engaged, Edit, MultiEdit and the MCP edit tool are gated like new files, except under declared `prototype_paths`. An exposed L3's learning delivery that extends its end date or changes its channel or data needs a recorded change with the gates re-run. Prior: 0.290.0 the release gate closes three holes, and the safety gates refuse when they cannot read.**The release gate closes three holes, and neither safety gate lets work through when it cannot read the canvas** (MINOR, adds blocks). Phase migration stage 0b-1. Without PyYAML the release gate allowed and the build gate refused for a false reason; both now refuse and name the fix, and they use Mycelium's own environment (created by /mycelium:setup on request, in the plugin's data directory) when the PATH python3 lacks PyYAML. The release gate counts tunnels and a push to a host that publishes on push, and stops counting release verbs that are only carried as text. Prior: 0.289.0 the safety net pinned before the phase migration.**The safety net pinned before the phase migration** (MINOR). Stage 0a of the migration ruled 2026-09-30: E2E run 10 (an SMS app built and put live under an L3 in define) is replayed on every release as a permanent test, and five holes open today are strict expected failures that stage 0b must close (editing product code, a tunnel, a push to a host that goes live on push, widening the audience, and the release gate failing open without PyYAML). stop-check reads the YAML instead of substrings, the outcome check sees completed_diamonds, exposure-change also runs after MCP writes, and version-discipline says what a breaking change is before 1.0.0. No new blocks. Prior: 0.288.1 a stored next item that is stale or settled is not offered again.**A stored next item that is stale or settled is not offered again** (PATCH). The prompt, resume and Stop hooks read `.claude/state/next-item.json`, which only session start rewrites, and checked only ledger rulings: the dogfood state, written by 0.254.1, kept offering `fired:ht-046` six days after it was ruled in active.yml. Every reader now shares one check: a state from another release is silent until the next session start, and a fired proposal is settled once the record no longer offers it. Prior: 0.288.0 an override never waives what an L4 delivers.**An override never waives what an L4 delivers** (MINOR). The scale-lock override could waive an L4's whole chain, so an L4 with no L3 behind it and nothing named as its object passed the lock; the dogfood L4 shipped five months of releases that way. An override may still waive the L3 and its evidence, which is the user's call to ship an untested bet, but an L4 with no L3 must name the solution it delivers in `object_ref`, and no ack lifts that. Prior: 0.287.2 a released L4 with its launch data recorded is told what the L5 lock still misses.**A released L4 with its launch data recorded is told what the L5 lock still misses** (PATCH). The next item asked for launch data whenever the L5 lock failed and a release date existed, so an L4 on an override with no L3 parent, released and with its launch data recorded, was asked to record it again and the missing parent was never shown. It now names what the lock reports, and the picker honours `state: archived` (or parked, killed) as closed, as scale_locks already did. Prior: 0.287.1 a closing-path proposal ruled on the record stops being offered.**A closing-path proposal ruled on the record stops being offered** (PATCH). diamond-assess tells the agent to settle a CLOSING PATH FIRED proposal that chooses no path by writing `ruling:` and `ruled_at:` under it, and derive_closing_path keeps those keys; the next-item picker never read them, so the dogfood L1 offered `fired:ht-046` as its top item for 13 days after the ruling. Ruled entries are now skipped; unruled ones still come. Prior: 0.287.0 a leaf's missing record is said at the write, and moved entries keep their address.**A leaf's missing record is said at the write, and moved entries keep their address** (MINOR). The dogfood canvas's remaining validator warnings traced to two sources. Leaves written straight into opportunities.yml reached a terminal status with no cycle row (23) or arrived with no purpose stance (7), and the validator named them days later; `post-write-nudge.sh` now names what the leaves a write touched still owe, at that write. And 11 of 13 dangling pointers named entries the canvas's own restructures had moved into lists (`moved_from`, `former_key`, `leaf_id`, `kind` plus `date`, the shape the key-shape guard recommends), schema notation, or a plugin engine file; the resolver now reads all of them. Prior: 0.286.3 on Codex, the next item names a skill the way Codex users type it.**On Codex, the next item names a skill the way Codex users type it** (PATCH). Codex lists Mycelium's skills as `mycelium:x` and its users mention a skill with `$`, while every item said `/mycelium:x`. The human line now renders `$mycelium:x` when the hook runs under Codex (`MYCELIUM_RUNTIME=codex`), and the operating contract tells the agent the mapping. Prior: 0.286.2 Codex logs shell reads too.**Codex logs shell reads too** (PATCH). `read-log.sh` took `Read|Bash` on Claude Code since v0.143.0 and `Read|read` in the Codex file, and Codex has no Read tool, so on Codex no read was ever logged and `verify_citations.py` had no ground truth for what the agent opened. A matcher-parity test now compares every hook's tools across the two files, with the by-design differences named. Prior: 0.286.1 a file written by an interpreter one-liner is a write.**A file written by an interpreter one-liner is a write** (PATCH). On Codex CLI 0.158.0 with Mycelium's hooks trusted, the shell hooks ran, and the agent still created app/hello.py in a project with no discovery, through `python3 -c 'Path("app/hello.py").write_text(...)'`: the shell-write parser recorded a write_text with no path, and the discovery gate skips those. A literal path in `Path(...).write_text/bytes` or `writeFileSync(...)` is now a target, quoted or escaped. Prior: 0.286.0 Mycelium on Codex runs its own hooks, and says when none run.**Mycelium on Codex runs its own hooks, and says when none run** (MINOR). Measured on Codex CLI 0.158.0 from the marketplace: all 63 skills loaded; with the hooks untrusted no hook ran and a source file was written with nothing said; with them trusted the session-start contract held. A new `.codex-plugin/plugin.json` points Codex at a hooks file derived from hooks.codex.json (without it Codex fell back to hooks.json and would drop its four async hooks); the guard for off-switch files refuses on Codex, which turns a hook's ask into an allow; the entry skills check a marker the hooks write and tell the user when it is missing; and start's first check no longer reads an unset CLAUDE_PROJECT_DIR. Prior: 0.285.0 a snoozed door wakes when the product changes.**A snoozed door wakes when the product changes** (MINOR). In the E2E relay on 0.283.0 the builder added features to the recipe code by editing an existing file, the founder snoozed the L1 door "until asked", and nothing was offered for the rest of the run while the product was built outside the ladder; service run 10 went silent the same way for 12 sessions. A snooze until asked on a way into the ladder, or on the ladder itself, now ends when a product file changes after the ruling, not counting what the ruling session wrote; the item says why it is back. Evidence does not wake it, and other items and dated snoozes keep their ruling. Prior: 0.284.0 the outside trial is Develop's, not a release.**The outside trial is Develop's, not a release** (MINOR). In the E2E relay on 0.283.0 the L3's Develop -> Deliver gate asked for one trial outside the team of what the delivery puts in front of people, and the exposure line said nothing built may meet real people before Deliver; the builder read both correctly and refused to let one tester paste a recipe into the page, so the gate could only pass by the founder running the trial behind Mycelium's back. While an L3 is in Develop the exposure line now names that one trial as Develop's own evidence, and the L3's Deliver item says it comes first. Prior: 0.283.0 an untried opportunity's door comes first.**An untried opportunity's door comes first** (MINOR). In the E2E service run 9 two L2s could open an L3; Mycelium offered the first in file order, whose L3 had completed and whose solution was already in production, session after session, and never the untried L2 the new L5 was about; the founder had to ask for it herself. Among parents whose lock holds, one that never had a child at that scale is now offered first; file order holds within each group, and the served one still comes next. Prior: 0.282.0 Deliver is not released.**Deliver is not released** (MINOR). In the E2E relay on 0.280.0 the L4 reached Deliver with the founder's public post on hold, and the next item said "has shipped" and told the agent to record the release seven sessions running; the builder rightly declined, since nothing had gone out. The shipped-L4 item is now three steps: with no `released_on` it is the founder's, to say when the L4 reaches its users; once released, recording the launch data is the agent's; once the lock holds, the L5 door. Prior: 0.281.0 an off-switch is the user's to write, in every project.**An off-switch is the user's to write, in every project** (MINOR). In the E2E relay on 0.280.0 the builder, running with permissions bypassed, wrote its own scale-lock override ("My judgment call, my override") and opened an L4 past its lock. A write to a file that switches a gate off returned `ask`, and in that mode nobody is asked; the three guards that asked were each conditional, so an ordinary project had no guard on the ack files at all, while the scale-lock docs said the agent gets an ask. A new gate in every project asks where a person is asked and refuses where nobody is. Prior: 0.280.0 an item only its doing can answer is not snoozed until asked.**An item only its doing can answer is not snoozed until asked** (MINOR). In the E2E service world run 7 the pilot's start item was snoozed "until real first-month-end data lands", data that exists only after the pilot starts, and the item for a delivery past its last day was snoozed the same way; the founder asked for the same month-end data six sessions running and nothing said the pilot had never started. The ledger now refuses a snooze until asked on the start, deliver and delivery-over items and accepts a date; and a refused ruling exits 2, where it exited 0 and read as recorded. Prior: 0.279.0 a write that ends exposure is said at once.**A write that ends exposure is said at once** (MINOR). In the E2E rung L4-open on 0.278.0 one builder turn completed the L3 as handed to a new L4 still in discover, which left nothing cleared for real people, and then called the founder's public launch post "ready to post whenever you are"; she posted it. The exposure line speaks only at a prompt, and the state flipped inside the turn. A new advisory PostToolUse hook, exposure-change.sh, tells the agent right after the write that took the work from ready to not ready, with what is missing, once. Prior: 0.278.0 a gate never evaluated is pending, not passed.**A gate never evaluated is pending, not passed** (MINOR). E2E rung L4-define on 0.276.0 assessed an L4, ruled needs-evidence and wrote no gate result, since the skill's only instruction to record gates sat under the phase move; the closing path then printed "every gate reads pass; nothing to store" for a diamond with no gate status at all, and the L4 sat in discover for three sessions. The closing path now counts every gate the next transition needs and has no status as pending, the agent's to evaluate now, and /mycelium:diamond-progress records each gate's result on every outcome. Prior: 0.277.0 a test past its score date is scored by Mycelium.**A test past its score date is scored by Mycelium** (MINOR). In the E2E rung L4-open on 0.276.0, 4 of 5 testers came back against a frozen bar of 3; the builder offered to write the result ("say the word") and did not, the verdict item fired only on a file already marked scored, and 0.276.0's ladder line "It waits on its learning delivery ending" was read as the whole L3 waiting and snoozed. An L3 test still live past its `score_by` is now the agent's to score from the notes, or to re-date with the reason; the ladder says only the move waits, not the verdict; and the line beside the request, which told the builder to put every escalated item to the user, now says to do an agent's item, from the first session (rung L5-open on 0.276.0 asked the founder to rule on the launch record). Prior: 0.276.0 a move that can happen now is proposed first.**A move that can happen now is proposed first, and an item says what to do** (MINOR). E2E rungs on 0.275.x: an L3 whose pilot was still running led the ladder every session because its notes kept arriving, and the L4 whose next move was desk work waited below it (L4-develop reached develop 1 of 3); the L4 was opened with no bar and two sessions went on asking the founder to write one she had decided; and the launch-data item borrowed the verdict's instruction, so the builder held the launch figures two sessions asking "say the word". A move that waits on the world (an L3 whose learning delivery has not ended) now follows one that can happen now; a bare L3-L5 gets its definition of done drafted from the founder's decisions, for her to confirm; and an agent-owned item carries its own instruction. A learning delivery past its last day now asks how it ended whatever was snoozed before (service world run 5 ran a month past it, clients still paying, no L4), and a hand-typed `ended.on` is read: `on` is a YAML 1.1 boolean and loaded as the key True. Founder: propose a move once what it needs is on record. Prior: 0.275.1 recording the launch is Mycelium's work.**Recording the launch is Mycelium's work, and the item names the fields** (PATCH). In the E2E rung L5-open on 0.275.0 the shipped-L4 item was put to the founder for four sessions, and the builder wrote the launch figures into a log entry the L5 lock never reads. Until the release and its launch data are recorded, the item is the agent's and names `released_on` and `launch_data: {..., as_of}` on the L4; the L5 door stays the founder's decision. Prior: 0.275.0 launch data comes after the release.**Launch data comes after the release** (MINOR). In the E2E rung L5-refused, with the launch withheld, the builder wrote the L3 pilot's five-tester results into the L4's launch_data ("forum page opens: 0") and the L5 lock, which read only that usage was filled, opened the L5. The L4 now records `released_on`, and the L5 lock needs `launch_data.as_of` after it. Prior: 0.274.0 a learning delivery's start is on the record.**A learning delivery's start is on the record** (MINOR). The E2E service world's L3 reached Deliver and grew its client pack from 4,100 to 7,100 words over seven sessions while nobody was served; 0.273.0 caught a growing build only in develop. `learning_delivery.started` records the day the first person took part; until it is set, the next item offers the start, and once overdue tells the agent to cut the build to what the start needs. Prior: 0.273.1 a duplicate key is named as it is written.**A duplicate key is named as it is written** (PATCH). YAML keeps a duplicate key's second value and drops the first without a word; the full canvas validator reported it, the check that runs as a file is written did not. The E2E service world wrote three into threat-model.yml and nothing told the builder. Prior: 0.273.0 an L3 builds only what its test needs.**An L3 builds only what its test needs** (MINOR). The E2E service world grew 8,500 words of client documents for a two-month, hand-run pilot with three existing clients, each edge case a new question for the founder, and the pilot never started. The L3's learning-delivery item now says to build only what the test needs, and once overdue tells the agent to stop extending the build and send every other open question to the tree as the next assumption, or to L4. Founder: "that's the ost working its way." Prior: 0.272.0 Mycelium records its own verdicts.**Mycelium records its own verdicts** (MINOR). In the E2E service world the pilot met the bar its test was frozen with, and the verdict item was put to the founder for three sessions as "Decide one: run | rule | snooze | drop"; the builder left it for her, nobody wrote it, and the L4 stayed locked. A next item now says whose it is: recording a verdict is the agent's to do now, told to the founder as being recorded; a door, a release or a pivot stays the founder's decision. Prior: 0.271.1 the security scope has its own key.**The security scope has its own key** (PATCH). 0.271.0 recorded the scope under `scope`, the name threat models already use for their sentence on what is modelled, so the E2E service world's threat model failed the canvas check on its next write. It is `security_scope` now; a written `scope` is valid again. Prior: 0.271.0 security and privacy checks fit what the product holds.**Security and privacy checks fit what the product holds** (MINOR). Founder: "2fa and so on might not be applicable for all products." `/mycelium:security-review` now records the product's scope first (runs code, accounts, personal data, money, reach) and applies only the checks it calls for, the rest recorded n/a with a reason; a service handled by people has its own section; privacy controls are proportional; and theory-gates no longer calls an offline service's Security gate N/A, which the lock could never honour. Prior: 0.270.0 the delivery gate sees a product that is not code.**The delivery gate sees a product that is not code** (MINOR). The E2E second world, a bookkeeping service with no software, wrote its client agreement, intake checklist and price sheet with only an L0 in discover; the gate knew code by its extension and skipped every document. A project now records `product_paths` (where its own files live), new files there are gated whatever their kind, and the next item asks once an L0 exists. Prior: 0.269.0 evidence and test sizing fit the product type.**Evidence and test sizing fit the product type** (MINOR). The rest of the overfit audit: the L4's per-transition evidence is keyed by product type (a course, an AI tool or a service is no longer asked for code tests); the L3's Develop->Deliver asks for one trial outside the team in the form the product takes, not a software prototype; and test sizing records reversibility, reach and harm, derives the class from them, and reports a test too light for its decision as well as too heavy, with the decision owner able to accept either with a reason. Prior: 0.268.0 the learning-delivery rules fit builders beyond the test world.**The learning-delivery rules fit builders beyond the test world** (MINOR). An audit of 0.258.0-0.267.0 against eight builders (a course pilot, a concierge service, a hardware loan, an internal team, a staged app beta, an open-source pre-release, a non-English founder, a project without git) found the 0.267.0 rules shaped to one simulated web page. How a delivery ended is recorded as fields, never matched as words; an audience change is recorded with its kind (narrowed, reworded, widened with its gates re-run, or everyone, the L4's); a repair reads the fresher record before the commit; an inconclusive test and a delivery past its end date each get a way on. Prior: 0.267.0 an L3's learning delivery keeps its audience.**An L3's learning delivery keeps its audience, and ends when the L3 does** (MINOR). The E2E rung L4-open made its page public under the L3, on Security and Privacy passed for five testers, and completed the L3 with the page still up. Widening the audience of an L3 that delivers now needs an L4 on it; an L3 completes by recording how its learning delivery ended (taken down, or handed to its L4); a completion written straight into completed_diamonds is judged like any move; and the L4 door names the audience it is the way past. Prior: 0.266.0 a broken diamonds file can be repaired.**A broken diamonds file can be repaired** (MINOR). The E2E rung L4-ship broke diamonds/active.yml with a shell write; the shell check said to fix it with Edit, and the scale lock refused the Edit as opening every diamond in it, since a file that does not parse read as no diamonds. A repair is now judged against the last good state (the committed file, else the scale and phase Mycelium recorded); anything the repair changes is still judged. Prior: 0.265.0 a verdict the lock cannot read is asked for again.**A verdict the lock cannot read is asked for again** (MINOR). An E2E rung recorded a correct pass as prose ("met on 2026-11-18 ... 4 of 5"); the L4 lock reads only its own words and stayed shut, and the verdict item stood down because the field was not empty. It now fires on an unreadable verdict and asks for `validated` or `invalidated`, reasoning in `verdict_note`. Prior: 0.264.1 the lock verdicts are pinned against reordering.**The lock verdicts are pinned against reordering** (PATCH). Metamorphic tests: reordering diamonds, opportunities or solutions, or adding a parked diamond elsewhere, never changes which diamonds hold or whether the L4 and L5 may open. Tests only. Prior: 0.264.0 a test is sized to the decision it informs.**A test is sized to the decision it informs** (MINOR). E2E runs 53-55 pre-registered a re-test for a five-tester recipe page that needed twelve blind recipe lines and a government dataset, and stalled on inputs nobody could supply. `/mycelium:assumption-test` now classes the decision (light, standard, heavy) and picks a test no heavier; the instrument check reports OVERSIZED tests; the founder can override with a written reason. Prior: 0.263.0 a failed assumption offers the way on.**A failed assumption offers the way on** (MINOR). E2E run 53 recorded `invalidated` on its L3's riskiest assumption; the L4 lock refused correctly and the next session offered nothing. A new next item offers the three exits: revise and re-test (back to define), the next solution from the L2, or stop the L3 with a reason. Prior: 0.262.0 the L3's JTBD and Privacy gates are phased too.**The L3's JTBD and Privacy gates are phased too** (MINOR). E2E run 50 held its L3 in discover on JTBD `fail` ("the emotional and social sides are unknown") and Privacy `pending` ("can't pass until the page is built"), two design-time gates read as needing evidence from use. Their L3 rows now say what each transition asks: JTBD, the three dimensions stated to define and served by the design to develop; Privacy, privacy by design on the design to develop and the build checked against it to deliver. Prior: 0.261.0 the L4's threshold is its exit bar too.**The L4's threshold is its exit bar too** (MINOR). E2E run 47 held the first L4 any run has opened in discover at confidence 0.15 against 0.7: the L4's field started at the default and its threshold was read at its first transition, duplicating the lock that had just admitted it on a test-validated verdict. The L4's threshold now applies at deliver -> complete, and each transition names its own evidence. Prior: 0.260.0 a scored test asks for its verdict.**A scored test asks for its verdict** (MINOR). E2E run 46 delivered its L3 to five testers, 4 of 5 came back against a bar of 3, and the builder scored the test file; it never wrote the verdict on the riskiest assumption, which is all the L4 lock reads, and nothing asked for it. A new next item names the scored file and asks for the verdict, and the verdict is defined on the bet the solution needs, whichever way the statement is worded. Prior: 0.259.0 the L3's bars rise with its phases.**The L3's bars rise with its phases** (MINOR). E2E runs 42-43 held an L3 in discover for three in-world months: its 0.75 confidence threshold and "prototype tested with users" were read at every transition, so it could not define before it had the prototype it exists to produce, a higher entry bar than the L4's. The L3's threshold is now its exit bar, and each transition names its own evidence: a real problem to define, a named test to develop, a prototype met by users to deliver, the learning delivery's verdict to complete. Prior: 0.258.0 the L4 opens only on the verdict of a learning delivery.**The L4 opens only on the verdict of a learning delivery** (MINOR). E2E run 41 scored a hand-run trial at a real site with its L3 still in develop and the backup approver timed without being told; one recorded verdict would have opened the L4, and only the builder held it back. The L4 lock now also needs the L3 in Deliver with `learning_delivery` recorded; any means counts, a concierge or hand-run test included, and after an early pass the next item keeps proposing the L3's Deliver. Prior: 0.257.1 commands Mycelium shows run this plugin's own script.**Commands Mycelium shows run this plugin's own script** (PATCH). The next item named `advisory_ledger.py` with no path; in E2E run 32 the agent searched for it, ran a copy 37 versions old from the plugin cache, and the founder's answer was stamped with a date before the question, so the item kept escalating after it was answered. Every shown command now carries the plugin's absolute path, and the answer prompts say which ruling fits which answer ("not now, ask me after X" is a snooze until asked with X as the note). Prior: 0.257.0 the L3 delivers to learn, the L4 to earn.*
*Full version history: [`docs/changelog.md`](docs/changelog.md).*
Mycelium is a harnessing system for AI-assisted product development. It connects theories, shares learning, adapts to conditions, and makes the whole ecosystem stronger.
**You are an agent operating within Mycelium. Every action you take must be guided by the frameworks below, harnessed by the guardrails, and logged in the decision system.**
## Agent Operating Contract (always-on rules)
The always-on behavioral rules — the **Communication Rules** (plain-language-first; suggest-skills-at-transitions; route-through-skills with the freeform escape valve; cite-the-trigger; offer-to-capture-learnings; name-the-verification-surface incl. `Ran: <cmd> → <result>` for runnable artifacts, `G-V13`; name-the-gate; read-canvas-before-narrating; verify-after-write; BLUF-layering, `G-C1`) and the **Mandatory Pre-Task / Pre-Ship (G-P-pre) / Post-Task (G-P7) Protocols** — are defined once, canonically, in **[`plugins/mycelium/engine/agent-operating-contract.md`](plugins/mycelium/engine/agent-operating-contract.md)**.
That file is the single source of truth, and the SessionStart handlers (`plugins/mycelium/hooks/contract-part.sh`, in parts under the hook output cap) inject it into every session — so the contract binds in **plugin form** too, where no operating-manual `CLAUDE.md` is templated into the consuming project. It is the plugin-form replacement for the removed legacy `degit`-templating path (the migration kept the computational half of the harness — hooks — but until v0.58.0 silently dropped this always-on inferential half for plugin-form consumers; the framework repo never noticed because its own sessions load this very file as the repo's `CLAUDE.md`). Read the contract; those active rules win over any restatement. **CI Check 47** keeps the wiring intact: contract present + packaged in `manifest.yml` + injected by the hook + referenced here + free of legacy `.claude/` framework paths.
Canonical detail behind individual rules still lives in the harness: `plugins/mycelium/harness/communication-rules.md` (rationale + graduation history + X/Twitter extraction sequence), `guardrails-core.md` (`G-C1` BLUF-layering, `G-V13` runtime-proof, `G-P7` Post-Task, `G-P-pre` Pre-Ship), `engine/canvas-guidance.yml#action_flags` (gate flags). Pre-Ship graduated 2026-05-04; write-narration-verification 2026-06-05 (#18/#19).
## The Diamond Engine
### Diamond Scales (L0-L5)
| Scale | Focus | Primary Theories | Canvas Files |
|-------|-------|-----------------|--------------|
| L0: Purpose | Why we exist | Sinek (Golden Circle), JTBD (Christensen) | `canvas/purpose.yml`, `canvas/jobs-to-be-done.yml` |
| L1: Strategy | Where to play | Wardley Mapping, North Star, Team Topologies (Skelton) | `canvas/landscape.yml`, `canvas/north-star.yml`, `canvas/team-shape.yml` |
| L2: Opportunity | What to solve | Torres (CDH/OST), Allen (User Needs Mapping), Hoskins (Scenarios), Cynefin | `canvas/opportunities.yml`, `canvas/user-needs.yml`, `canvas/scenarios.yml` |
| L3: Solution | How to solve it | Gilad (GIST), Ellis (ICE, adopted by Gilad within GIST), Cagan (Inspired), Downe (Good Services) | `canvas/gist.yml`, `canvas/services.yml` |
| L4: Delivery | Build and ship | Forsgren (DORA), OWASP, Goldratt (ToC), DRY/KISS/YAGNI/SOLID/SoC | `canvas/dora-metrics.yml`, `canvas/threat-model.yml`, `canvas/value-stream.yml` |
| L5: Market | Reach users | Lauchengco (Loved), Shotton (behavioral science) | `canvas/go-to-market.yml`, `canvas/trust-signals.yml` |
L0-L3 are product-agnostic. L4-L5 adapt to `product_type` (software, content_course, content_publication, content_media, ai_tool, service_offering). See `canvas-guidance.yml#product_types`.
### Diamond Phases
Four phases per diamond, gated by theory checks: **Discover** (diverge — explore, gather evidence), **Define** (converge — synthesize, frame the problem), **Develop** (diverge — ideate, prototype), **Deliver** (converge — validate, build, ship, measure). Diamonds spawn children (L0→L1→L2→L3→L4, L5→L2 on market feedback); a bad assumption found in delivery **regresses** the diamond back with new evidence — the system working correctly. Full transition rules, WIP limits, lifecycle: `plugins/mycelium/engine/diamond-rules.md`.
### OST Leaf Lifecycle
Every solution leaf runs a 10-phase pipeline, each phase with input artifacts, gates, outputs, and discard criteria: **OST Leaf → Four Risks → ICE Score → Assumption Test → GIST Entry → Bounded Context → Threat Model → Preflight → Delivery Diamond → Launch + Feedback**. Definitions and discard rules: `plugins/mycelium/engine/leaf-lifecycle.md`; archived leaves → `canvas/archived-solutions.yml`.
### Perspective Resolution & Leaf Bakeoff
Conflicting product/design/engineering perspectives → structured resolution in `plugins/mycelium/engine/perspective-resolution.md`. Multiple leaves competing for one opportunity → structured A/B comparison in `plugins/mycelium/orchestration/leaf-bakeoff.md`.
## Theory Gates (Decision Checkpoints)
Every diamond transition must pass applicable gates from: Evidence, Four Risks, JTBD, Cynefin, Bias, Security, Privacy, BVSSH, Service Quality, Delivery Metrics, Corrections, Regulatory, Explainability, Landscape, Capacity. See `plugins/mycelium/engine/theory-gates.md` for complete definitions, pass/fail criteria, and suggested skills.
**You cannot progress a diamond by saying "I'm confident enough." You must demonstrate evidence that satisfies each gate.**
## The Canvas (Source of Truth)
All product knowledge lives in `.claude/canvas/*.yml`. These files are:
- The **single source of truth** for the product's state
- Committed to git (they are documentation-as-code)
- Updated through evidence, not assumption
- Readable by any team member starting a new session
**Never make a significant decision without first checking and updating the relevant canvas file.**
Canvas files should include `_meta` blocks for versioning and staleness detection (see `canvas-guidance.yml`). Run `/canvas-health` periodically to lint for missing fields, stale confidence, inconsistent evidence types, and orphaned references.
**Canvas writes — Read before Write (HARD RULE).** Canvas files ship pre-populated, so every `.claude/canvas/*.yml` exists on a fresh project. `Write`/`Edit` require a prior **`Read` tool** call (same session); **`cat`/`head`/`grep` via Bash do NOT satisfy it** (different tool surfaces). **`Edit`**: `Read limit:1` suffices (~50 tokens; state is per-file — reuse across edits; use for large files like `purpose.yml`). **`Write`**: full Read first (it obliterates the file). **ID-bearing entries**: run `grep "^ - id: <prefix>-" .claude/canvas/<file>.yml | sort -u` before assigning and pick the next free integer (`validate_canvas.py` catches dupes on CI but a working-tree dupe can persist for days; kin to anti-pattern #8 Stale State Read). Validator Check 31 enforces the Preflight block; cost-discipline + ID-scan graduation history in `docs/changelog.md`.
## Harnessing System
- **Behavioral Contract** (`plugins/mycelium/harness/behavioral-contract.md`): Consolidated must / must-never index for the agent itself. Pointer-only (copies nothing; the cited source always wins) so the agent's own behavioral contract is grep-able in one place — the self-governance analogue of the `ai_tool` product contract in `canvas/ai-tool-metrics.yml`.
- **Guardrails** (`plugins/mycelium/harness/guardrails.md`): Three-tier enforcement -- BLOCK (mechanically prevented), REVIEW (gates progression), NUDGE (advised, not blocking).
- **Anti-Patterns** (`plugins/mycelium/harness/anti-patterns.md`) & **Cognitive Biases** (`plugins/mycelium/harness/cognitive-biases.md`): Known failure modes with detection rules (stop and self-correct if you catch yourself in one); per-stage bias checklist.
- **Security & Trust** (`plugins/mycelium/harness/security-trust.md`): Per-stage security requirements.
- **Engineering Principles** (`plugins/mycelium/harness/engineering-principles.md`): DRY, KISS, YAGNI, SoC, SOLID, LoD. Human-facing complement: **Design Principles** (`plugins/mycelium/harness/design-principles.md`) — how the framework treats its user (SDT autonomy/competence/relatedness; Theory Y; never gamify discipline).
- **Delegation Authority** (`plugins/mycelium/harness/delegation-authority.md`): who decides — agent vs human — for each *execution* decision, keyed to consequence (effective-reversibility × aggregate-blast-radius). Binds the BLOCK/REVIEW/NUDGE tiers to execution (not just epistemic discipline); names the no-standing decisions (which bet, security/privacy/ethics tradeoffs, editing the map itself) that are absolutely human; round-up-under-uncertainty; escape-hatch override. Repo anchor for behavioral-contract N9/N10.
## Self-Learning System
### Two Memory Systems -- Important Distinction
| System | Location | Scope | Committed to git? |
|---|---|---|---|
| **Project memory** | `.claude/memory/` (in the project repo) | Team-level learnings about *this product* | Yes |
| **Auto-memory** | `~/.claude/projects/<id>/memory/` (in user home) | Per-session continuity between you and the agent | No (user-local) |
**Routing rule**: Project-team learnings -> project memory. Agent-user learnings -> auto-memory. Hardware/environment failures -> neither.
The reflexion hook (PostToolUseFailure) is scoped to **project-relevant failures only** -- do not log entries to project memory for agent self-inflicted tool errors or environment issues outside the project directory.
### Key Artifacts
- **Corrections** (`.claude/memory/corrections.md`): learning from mistakes. **Read before every task.** *Recourse SLA*: one-offs inform next session; ≥3 same-root-cause instances graduate to mechanism on the next L4 cleanup cycle.
- **Patterns** (`.claude/memory/patterns.md`): successful patterns to reuse.
- **Warnings Log** (`.claude/memory/warnings-log.md`): CI WARN+FAIL capture, auto-updated; per-class fixes in `plugins/mycelium/engine/warning-handbook.md`; consumed by `/corrections-audit`.
- **Decision Log** (`plugins/mycelium/harness/decision-log.md`): every significant decision. **Required** `why_not_alternatives` field — per-alternative rejection rationale; contrastive explanations land harder (Liao et al. 2020) and feed `/xai-check` Stage 2.
- **Feedback Loops** (`plugins/mycelium/engine/feedback-loops.md`, `/feedback-review`), **Reflexion Loop** (`plugins/mycelium/skills/reflexion/SKILL.md`, max-3 retry), **Eval Benchmarks** (`.claude/evals/`), **Cycle History** (`.claude/canvas/cycle-history.yml` → `engine/cycle-learning.md`), **Adaptive Thresholds** (`.claude/canvas/thresholds.yml` → `engine/adaptive-thresholds.md`).
### Learning Metabolism (Self-Improving System)
Five mechanisms make Mycelium smarter over time (details + cadence in each sub-file): **Cycle Learning** (`plugins/mycelium/engine/cycle-learning.md` — predicted vs actual ICE), **Pattern Emergence** (`plugins/mycelium/engine/pattern-detector.md` — into `/retrospective`, `/diamond-assess`), **Adaptive Thresholds** (`plugins/mycelium/engine/adaptive-thresholds.md` — defaults until N=10), **Framework Reflexion** (`plugins/mycelium/engine/framework-reflexion.md`, `/framework-health`), **Evidence Decay** (`plugins/mycelium/engine/evidence-decay.md` — `/canvas-health` flags stale evidence).
## Domain Contexts
Load the appropriate context based on current diamond phase:
- **Discovery**: `${CLAUDE_PLUGIN_ROOT}/domains/discovery/CLAUDE.md` -- Torres-style interviewing, OST construction, bias-aware research
- **Delivery**: `${CLAUDE_PLUGIN_ROOT}/domains/delivery/CLAUDE.md` -- Agile/DevOps practices, clean code, security, accessibility, DORA metrics
- **Quality**: `${CLAUDE_PLUGIN_ROOT}/domains/quality/CLAUDE.md` -- Always-active overlay: validation, accessibility, security, service principles
## JiT Tooling
Mycelium is **language-agnostic** and **product-type-agnostic**. When a delivery diamond begins, auto-detect the tech stack (or product type), generate appropriate validation, and confirm with the user. See `plugins/mycelium/jit-tooling/detector.md`.
## Usage & Orchestration
Solo developers use canvas as shared memory with the agent. Teams commit canvas to git as shared product documentation. For parallel exploration, use `/fan-out` with worktree-isolated worker agents.
See `plugins/mycelium/orchestration/modes.md` for usage patterns and `plugins/mycelium/orchestration/agent-teams.md` for parallel orchestration.
## Operations & Maintenance
- **Day-to-day**: `plugins/mycelium/orchestration/operations.md` -- Session resumption, canvas maintenance, diamond lifecycle, memory pruning
- **Escape hatch**: `plugins/mycelium/orchestration/escape-hatch.md` -- Legitimate process bypass for emergencies. Must be documented and paid back.
## Skills
All 63 skills are auto-discovered from SKILL.md frontmatter — in plugin form (`plugins/mycelium/skills/*/SKILL.md`, recommended) or legacy form (`.claude/skills/*/SKILL.md`, supported during transition). Suggested skills are surfaced at diamond transitions by `/diamond-progress` and `/diamond-assess`, and contextually by hooks. Type `/` to see the current list.
## Getting Started
New project (empty canvas): run `/interview`. Continuing work (populated canvas): run `/diamond-assess`. The system guides you from there.