# @geonosis/cli

## 3.7.0

### Minor Changes

- 3251966: `geonosis init` measures `typescript/no-explicit-any` for `frontend` (#158), and with `i18n` the react plugin's rules that catch real bugs (`jsx-key`, `iframe-missing-sandbox`, `jsx-no-script-url`, `refs`, `set-state-in-effect`, `jsx-no-duplicate-props`, `jsx-no-undef`, `no-children-prop`, `no-danger-with-children`; #195) before it enforces them. A rule that finds nothing is written at `error`. One that finds something is parked at `off` beside an `oxlintRule` counter `census:<rule>` that may only shrink, whose number the ratchet adopts at its first run; `geonosis ratchet --prove` plants a finding for it. `geonosis update` adds the same census to a repo that lacks it, through a new `census` post-update step: it asks oxlint what `.oxlintrc.json` resolves each rule to (`oxlint --print-config`), leaves a rule that resolves to on — under any spelling, at any level, through `extends`, an override or a category — and measures the others as init does, writing a rule that finds nothing at `error`. A config oxlint cannot resolve fails the step, and nothing is written. The plugin exports `censusOf` and `CENSUS_PRESETS`, the one list both read, from its root and from `./presets`.
  
  Why `any` is measured at all: removing 475 explicit `any`s from one storefront found five live bugs it had hidden, among them a price sort subtracting a field variants do not have, a review list reading `id` off deleted reviews, and a misspelled relation the backend ignored without an error.
- 1dabee8: JSONC is read by Microsoft's `jsonc-parser` in place of the comment-and-comma stripper `@geonosis/base` carried, and a wrangler config of any extension is read by wrangler's own config reader (`experimental_readRawConfig`), as a `wrangler.toml` already was:
  
  - **Refused now, as oxlint and wrangler refuse it:** a comment between two tokens, such as `1/* why */0`, which the stripper joined into `10`. The doctor, the ratchet's counters, lint-parity, the MCP preamble, `geonosis explain`, `create-geonosis --plan`, the evals scorer and `deriveLocalOnlyConfig` name the line of what they could not read.
  - **Read now:** a config whose lines end in a carriage return alone, which wrangler and TypeScript read and the stripper refused; the lint plugin reads such a `tsconfig.json`'s `paths`.
  - **`geonosis explain`** refuses, naming the file, when a file it reads does not parse, where it answered with defaults.
  - **New:** `@geonosis/ratchet` and `@geonosis/cli` export `parseJsonc`, which throws a `SyntaxError` naming the error and its line.
  - **Removed:** `@geonosis/base: parseJsonc` (`@geonosis/base` takes no dependency) and `@geonosis/release: parseJsonc`. Import `parseJsonc` from `@geonosis/ratchet`, or depend on `jsonc-parser`.
- 98a2c5a: `npxTool(id)` is exported: the `npx --yes --package @geonosis/<id> geonosis-<id>` command the Python law names its gates by. `create-geonosis --language py` writes its CI steps, its `full` tier and the line it prints after scaffolding from it, so the law and the tree it ships beside cannot name a gate two ways. The files it writes are unchanged.
- fb83671: `geonosis update` prints one `young` line for a release family: versions the lockfile gained that share a version and a repository (the registry's `repository` of that version, normalized, directory left out) (21 lines for `oxc-parser`, its 19 platform bindings and `@oxc-project/types`) become one line with the count, the repository, the version and the youngest publish time. `--verbose` lists each package, and `.geonosis/bump-report.json` keeps every one under `young` (#206).
- ef78e9d: `geonosis update` runs the doctor's checks before the repin with the copy installed then, and again after the install. Each WARN or FAIL present after and absent before, told apart by check and subject and not by message text, is a BY HAND item naming the check and its message, and is kept in `bump-report.json` under `byHand`. A rule the `loaded` check already lists as needing an option is not repeated; when the first run gives no findings report, the output says so and quotes the tail of what it answered. The doctor runs against the `home` the update was given (#198).
- 015ddf8: A re-run of `geonosis update` does not repeat the install, the frozen lock, the doctor or post-update when each was already green over the tree the re-run finds. Each is recorded after it passes with the mechanism `geonosis-verify` records a tier with (`.geonosis/green-update-<step>.json`, the tree hash and the way the bump was asked); the re-run resumes after the latest step whose record matches, shows those steps as `resumed`, and carries the doctor's BY HAND items from the last report. `--fresh` runs every step again. A verify or build step that timed out names the steps that had passed and says a re-run resumes after them (#186).
- 05fb7da: `geonosis update` writes each step's start and end, with its time and outcome, to stderr as it goes, and one line a minute naming the step and the time elapsed while a step runs. A bump that spent 23 minutes in an install or a test step is no longer silent for them. The lint step runs its child synchronously, so it prints its start and end and no line between (#166).

### Patch Changes

- c990bf2: The AGENTS.md that `sync --target agents-md` writes names the command that regenerates it as `geonosis ledger sync --target agents-md`, the spelling every consumer has; under pnpm `geonosis-ledger` is a command only where `@geonosis/ledger` is a direct dependency (#68). The new header makes `sync --target agents-md --check` fail on an AGENTS.md an older ledger wrote, so `geonosis post-update`, which `geonosis update` runs, regenerates an AGENTS.md whose header says the ledger wrote it, and leaves any other AGENTS.md as it is.
- 5b5e373: The `geonosis` door prints a tool's stdout on its stdout and the tool's stderr on its stderr. It used to print both on stdout, after its own note that it runs the copy that came with `@geonosis/cli`, so `geonosis doctor --json` printed text around the report and a reader of stdout could not parse it. The note goes to stderr. `geonosis --json <command>` still joins both in `output`, and `runBin` still returns them joined.
- 3e46e76: `geonosis <tool>` for a tool the door fronts (ledger, ratchet, verify, doctor and the rest) finds and starts the tool without loading the whole command registry; the registry is imported only for the door's own commands and its usage. Measured on bun 1.4.3 at load 19–20, `geonosis ledger delivery check --cached` took a median 379 ms against 139 ms for the ledger bin before, and 204 ms against 125 ms after; the door's own CPU went from about 190 ms to about 38 ms. The commit and push guards run the ledger through the door in a repo that installs only `geonosis`, inside a 2.5 s budget (#215, #68).
- 070a593: A command that fronts a bin finds the repo's own copy of the tool in the `node_modules` of the repo, from the directory it runs in up to the repo root (the nearest directory holding `.git`, `pnpm-workspace.yaml` or a `package.json` with `workspaces`, else the nearest holding a `package.json`), read off the filesystem, and otherwise the copy that came with `@geonosis/cli`, found from the cli's own location, and says so. Through the resolver, the repo lookup also took the pnpm virtual store that a pnpm bin shim puts on `NODE_PATH`, and on bun its global install cache, and a copy in a `node_modules` above the repo, so the cli's or another version's copy ran without the note. A repo's copy that declares a bin and no entry point is now found too (#68).
- aab823c: The full tier `geonosis init` writes ends with `pnpm exec geonosis ratchet` (`bunx geonosis ratchet` on bun), through the door its record steps use, where it ended with `pnpm ratchet` over a root that declares no `ratchet` script; a root that declares one keeps `pnpm ratchet`.
- 8301315: The rule files, skills, commands and agents spell the ledger `geonosis ledger …`, the command the metapackage links under every package manager; under pnpm `geonosis-ledger` is a command only where `@geonosis/ledger` is a direct dependency. The rule files `geonosis rules` copies and the `todo-names-its-plan` fix shape say it that way. The `@geonosis/cli` README says what a pnpm consumer installs directly: `geonosis` or `@geonosis/cli` for the door, which the plugin's hooks, the commit guard included, run where the repo links no tool of its own. The `geonosis` README no longer says the package ships no bin (#68).
- c19e51a: A message that tells a person what to run names it through the `geonosis` door: the baseline write refusal and the ratchet's FAIL name `geonosis ratchet --raise …`, an unproven fall `geonosis ratchet --bank …`, a missing or stale recording `geonosis ratchet --record …`, the session doctor `geonosis doctor`, the Stop hook, `geonosis verify` and the doctor's `runner` check `geonosis verify prove`, the ledger's handoff check `geonosis ledger handoff`, its push guard `geonosis ledger land --attest-only`, a plan envelope's next step `geonosis ledger plan check`, the release's smoke and migrations messages `geonosis release …`, each tool's `--help` and `--print-config-shape` pointers `geonosis <tool> …`, the write guard on `.geonosis/` `geonosis verify fast`, and init and post-update's census line name `geonosis ratchet` and `geonosis verify` for the gates init writes. Init no longer asks the root to declare `@geonosis/ratchet` and `@geonosis/verify` for their bins: its gates call the door. Under pnpm a tool's own bin is a command only where its package is a direct dependency (#68).
- d351529: `geonosis post-update` regenerates every `AGENTS.md` in the tree whose header says the ledger wrote it (`docs/AGENTS.md`, a package's own), outside `node_modules` and dot directories, beside the one `ledger.agents` names. It used to read only the root one, so a `docs/AGENTS.md` an older ledger wrote kept failing its `--check` after the update. An `AGENTS.md` the ledger did not write is still left as it is.
- 69be472: `geonosis post-update` names each tier command it leaves running the ratchet by its own bin (`geonosis-ratchet --record bare`, `./node_modules/.bin/geonosis-ratchet …`, `pnpm exec geonosis-ratchet --tier fast`), by its place in `geonosis.json`, and says it does not rewrite a spelling no older init wrote. A run that moved nothing used to say every tier command already runs `geonosis ratchet`, which was false while such a step was there.
- 22d3360: The law a Python repo starts with names its gates as the commands that work there: `npx --yes --package @geonosis/verify geonosis-verify fast` (and `full`) and `npx --yes --package @geonosis/doctor geonosis-doctor`, as its CI and `geonosis.json` run them. A uv repo has no `node_modules`, so the bare `geonosis-verify` it named was on no PATH.
- 74147f7: The fast tier `geonosis init` and `create-geonosis` write records each counted tool as `pnpm exec geonosis ratchet --record <counter>` (`bunx geonosis ratchet …` on bun), through the door every repo that installs `geonosis` has. Under pnpm `pnpm exec geonosis-ratchet` was `Command "geonosis-ratchet" not found` unless `@geonosis/ratchet` was a direct dependency. `geonosis post-update`, which `geonosis update` runs, moves the record steps an older init wrote to the same spelling, leaves every other byte of geonosis.json as it was, names each step it moved, and moves nothing on a second run (#68).
- 7819143: `geonosis update` counts the oxlint findings of a plugin bump over every oxlint config that loads the plugin, an `oxlint.config.ts` or `oxlint.config.mts` and a config a lint command names with `-c` included, where it used to count `.oxlintrc.json` files only. A config a lint command names is run over the paths that command lints, as the doctor's `downgrades` runs it, not over the config's own directory. A config in the tree that cannot be loaded makes the lint step fail naming it, rather than leaving it out of the count (#169). `@geonosis/doctor` exports `namedConfigTargets`, the configs the repo's lint commands name and the paths each lints.
- 9fbc4b3: `geonosis update --registry <dir>` run a second time over the candidate it installed lists the changelog entries above the version the tree came from, read off the last commit, where it used to read the `file:` pin it had written as no version and list every entry back to the first release. A `file:` pin the last commit holds is read as the version in its tarball's `package.json`, so a committed candidate lists none.
- 1fbd2df: `geonosis update` and `geonosis post-update` name the commands their steps ran as the door spells them: `geonosis doctor --only …`, `geonosis verify <tier>`, and `geonosis doctor` as the reader of `.geonosis/post-update.json`, in their reports and their `--help`, and `geonosis update --help` names `geonosis release smoke` as what writes a `--registry` directory. `geonosis sync --help` says a `--target` goes to `geonosis ledger sync`. Each named the tool's own bin, which under pnpm is a command only where its package is a direct dependency (#68).
- 821e940: `geonosis update --registry <dir>` under a lifted release-age gate names the young third-party versions the candidate brought in, asking `--npm-registry` (npm by default) when each was published, where it named none: the young check was skipped whenever the kit came from a directory. A version the registry gives no date for is a `young?` line, as on any other bump.
- b505542: A tool run through the door prints its usage the way it was run: `geonosis ratchet --help` says `geonosis ratchet [--cwd <dir>] …`, not `geonosis-ratchet …`, and the same for every tool the door fronts. The door tells the tool in `GEONOSIS_DOOR`, naming the bin it started, so a tool that tool starts in turn keeps its own name. `@geonosis/base/node` exports `doorSpelled`, `doorEnvFor` and `DOOR_ENV`. A tool run by its own bin prints its own name, as before (#68).
- Updated dependencies [c990bf2]
- Updated dependencies [1830b16]
- Updated dependencies [cd20fc3]
- Updated dependencies [3251966]
- Updated dependencies [91a10f2]
- Updated dependencies [49e4fcf]
- Updated dependencies [622b77d]
- Updated dependencies [d68c4a6]
- Updated dependencies [54174c9]
- Updated dependencies [415b7f5]
- Updated dependencies [6552c12]
- Updated dependencies [28e2edc]
- Updated dependencies [939ba84]
- Updated dependencies [66a5070]
- Updated dependencies [5533d4a]
- Updated dependencies [4d2068e]
- Updated dependencies [86e500e]
- Updated dependencies [261ead6]
- Updated dependencies [91e682b]
- Updated dependencies [5f8a04f]
- Updated dependencies [fcaa6ab]
- Updated dependencies [5ecf548]
- Updated dependencies [e0f0882]
- Updated dependencies [abe3d27]
- Updated dependencies [b329b94]
- Updated dependencies [1dabee8]
- Updated dependencies [4ad4e15]
- Updated dependencies [5376ef5]
- Updated dependencies [8301315]
- Updated dependencies [1e5cd61]
- Updated dependencies [c19e51a]
- Updated dependencies [fcc8655]
- Updated dependencies [5f03fe8]
- Updated dependencies [1974fe6]
- Updated dependencies [957ee47]
- Updated dependencies [74147f7]
- Updated dependencies [8eda0d0]
- Updated dependencies [b44a30f]
- Updated dependencies [d66da0e]
- Updated dependencies [1ecaf6c]
- Updated dependencies [c8b04c5]
- Updated dependencies [c45ecef]
- Updated dependencies [c67f5f9]
- Updated dependencies [60469d6]
- Updated dependencies [f9f4c10]
- Updated dependencies [d6d0c42]
- Updated dependencies [33a09bf]
- Updated dependencies [e7b4058]
- Updated dependencies [9af05d2]
- Updated dependencies [86e2584]
- Updated dependencies [49735bb]
- Updated dependencies [4882722]
- Updated dependencies [7819143]
- Updated dependencies [b505542]
- Updated dependencies [7a5ac6a]
- Updated dependencies [20a815f]
- Updated dependencies [7e2d814]
- Updated dependencies [3d313a8]
- Updated dependencies [f878b27]
- Updated dependencies [87c07b1]
- Updated dependencies [7b1e29c]
- Updated dependencies [838fa52]
- Updated dependencies [e0d7589]
- Updated dependencies [d37b566]
- Updated dependencies [2982125]
- Updated dependencies [f3d189f]
- Updated dependencies [281381c]
- Updated dependencies [cc48e0e]
- Updated dependencies [7492312]
- Updated dependencies [2e0aae2]
- Updated dependencies [8477932]
  - @geonosis/ledger@3.7.0
  - @geonosis/base@3.7.0
  - @geonosis/ratchet@3.7.0
  - @geonosis/oxlint-plugin-biological-architecture@3.7.0
  - @geonosis/doctor@3.7.0
  - @geonosis/verify@3.7.0
  - @geonosis/release@3.7.0
  - @geonosis/lint-parity@3.7.0
  - @geonosis/testbed@3.7.0
  - @geonosis/observability@3.7.0
  - @geonosis/review@3.7.0
  - @geonosis/verify-arch@3.7.0
  - @geonosis/walk@3.7.0
  - @geonosis/visual-diff@3.7.0

## 3.6.1

### Patch Changes

- 51a8306: The release-age refusal's override is the person's own `geonosis update` command, `--floor`, `--floors`, `--install-args` and the rest, with only the age lifted. Before, it was rebuilt from `--to` alone and ran a different bump (#192).
- b39b85e: `geonosis post-update` finds a BY HAND mark wherever an item of an entry starts, not only at the start of the entry, and lists that item alone. 3.6.0's `cf` item and 3.4.0's `backend-d1` item each sat inside a longer entry, so a repo bumping from below 3.5.0 was told that nothing was asked of it (#200). A mark quoted in backticks is not one. A changeset whose mark does not start its body now fails the kit's own tests.
- 55198ca: `geonosis update --install-args --min-release-age=0` is read: `--install-args` takes a value that starts with `--`, since every package manager's override does. Only `update`'s own flags are still refused there, with the `--install-args=<value>` spelling that hands one to the manager. Before, the override the release-age refusal printed was refused by `update`'s own parser on every manager. The refusal, `update --help` and the README now print the inline form, `--install-args=--min-release-age=0`. A test runs each printed command through a shell and back into `update` (#205).
- 51d0c46: The README names how an npm tree on a kit older than 3.5.0 bumps: its installed `update` refuses npm, so it runs the target version's own `update` through `npx -y --min-release-age=0 --package=geonosis@<version> -- geonosis update …`. That copy runs the whole ritual and its own `post-update` (#208).
- 8b44243: `geonosis update` reads an npm `package-lock.json`: the versions of every installed copy, nested ones included, and who depends on whom. Before, the lock-move report read lockfiles by `name@version` text, which an npm lockfile does not contain, so on an npm tree it never named a package the bump moved.
- 361c2db: `geonosis update` no longer holds a bump over a third-party package's age. Under an exemption, the manager's own cooldown governs third-party packages. Under the override you pass in `--install-args`, nothing is held, and after the install `update` lists each third-party version the lockfile gained that is younger than your cooldown, as `young` lines. That includes one a kit package the root never names brought in (#207), and never a version the tree already had and npm kept (#206). Before, under the override, `update` judged the newest release of every range the repinned packages declared. It refused an npm tree that pinned an older oxlint about 96% of the time, and never read what the rest of the fixed group pulled in.
- 1b88f19: The commit body `geonosis update` prints starts with one summary line: the versions, the floors moved, how many steps ran clean, and which did not run. Every line is within 100 characters. Before, it met the line count by putting every step's command on one 286-character line (#193).
- c415a65: `geonosis post-update` runs the doctor checks this version's `update` asks for and the updater that ran did not: `group`, and `release` where `geonosis.json` declares one, after an update made by a version below 3.6.0. It fails as this version's `update` would. post-update is always the copy just installed, so an older updater's bump into this version is now checked the same way (#201, #191). When the doctor step of `update` fails, it prints the doctor's FAIL, WARN and UNJUDGED lines rather than its JSON report. post-update still runs after it, so the notes that explain the failure are shown (#202). The commit body names `geonosis post-update --from <version>` for the notes and BY HAND items, rather than `.geonosis/bump-report.json`, which no commit carries (#203, #194).
- Updated dependencies [ecf5c52]
- Updated dependencies [71be23b]
- Updated dependencies [ac7f890]
- Updated dependencies [a852cb7]
- Updated dependencies [0716e00]
- Updated dependencies [39cbf70]
- Updated dependencies [be45c31]
  - @geonosis/verify@3.6.1
  - @geonosis/ratchet@3.6.1
  - @geonosis/base@3.6.1
  - @geonosis/testbed@3.6.1
  - @geonosis/doctor@3.6.1
  - @geonosis/oxlint-plugin-biological-architecture@3.6.1
  - @geonosis/release@3.6.1
  - @geonosis/ledger@3.6.1
  - @geonosis/lint-parity@3.6.1
  - @geonosis/observability@3.6.1
  - @geonosis/review@3.6.1
  - @geonosis/verify-arch@3.6.1
  - @geonosis/visual-diff@3.6.1
  - @geonosis/walk@3.6.1

## 3.6.0

### Patch Changes

- e65a3b0: Every temp directory a kit package makes is held by the process that made it (`<dir>.holder`, the process id), through `heldTempDir` from `@geonosis/base/node`. The holder goes when that process exits. Before, a sweep of unheld `geonosis-*` directories, run by any test run on the machine, could delete a live one. An evals session waiting on its model holds no file open, and lost its workdir that way 11 minutes into a scored run.
- 1ce783b: A preset that names one rule of an oxlint plugin brings in that rule and nothing else of the plugin (#177). The `i18n` preset's `react/jsx-no-literals` switched on oxlint's `react` plugin, and the config's `correctness` and `suspicious` categories then enabled all 42 react rules in them. On a React 19 storefront that meant 7,036 `react-in-jsx-scope` findings. `geonosis init` and `create-geonosis` now write each of those rules `off`, read from oxlint's own catalogue (`oxlint --rules --format=json`), which ships with the kit and is held against the installed oxlint by a test. An override cannot scope a plugin away from the categories: oxlint 1.88.0 refuses `categories` in an override, and a plugin enabled in an override is still reached by them.
- 053c4a2: - On a yarn 1 tree, `geonosis update` holds a bump to npm's `min-release-age` (`npm_config_min_release_age`, then the project `.npmrc`, then the user's). yarn 1 has no cooldown of its own, so that is the policy the user stated. A refusal names `npm_config_min_release_age=0 geonosis update --to <v>` as the way past it for one run (#185).
  - When `pnpm config get` cannot run, the pnpm reader reads `minimumReleaseAge` from `pnpm-workspace.yaml` (#171). When neither answers, it throws `ReleaseAgeUnread` instead of reporting no gate. `update` refuses with that sentence, and the `cf` advice says no version can be named past the gate.
- f275d25: The commit body `geonosis update` prints is the subject plus at most `ledger.commitMessageLines − 1` lines, read from the repo's `geonosis.json` (default 4). So the kit's own `geonosis-ledger commit-msg` accepts it (#165, #187). Before, it was 7 to 22 lines, and the gate refused it. The floors moved, the release notes, what did not run and the BY HAND work are printed above the body and kept in `.geonosis/bump-report.json`, which the body names. `@geonosis/base` exports `COMMIT_MESSAGE_LINES`, the default the ledger and the update share.
- 0a8958e: `geonosis update` asks the doctor for `loaded`, `group` and, where `geonosis.json` declares a release, `release`. Before, it asked only for `loaded`, so a bump could report PASS while the next full doctor, and CI, failed (#160, #163).
  - The doctor's `group` check reports a kit package that is installed but that no manifest asks for, and no kit package asked for depends on, once, as a WARN naming the `rm -rf` that removes it. It used to report that copy as a bump that landed halfway, once per workspace. bun's hoisted linker keeps a removed package on disk (#160).
  - A doctor finding with an OK verdict is no longer listed as BY HAND work (#175).
  - The skipped build step names the key it reads, `verify.build` (#164).
  - BY HAND (from <3.5.0; done by doctor): since 3.5.0 the release runner and `--record-bookmark` move traffic and take the D1 bookmark with Cloudflare's `cf` CLI. A Workers repo that releases through `geonosis release` installs `cf` and logs it in (`cf auth login`, or `CLOUDFLARE_API_TOKEN`). The doctor's `release` check names the version past the repo's release-age gate (#163).
- 3968b09: `geonosis update --prove` proves the package managers at once, each in its own scratch consumer against the one scratch registry, and reports them in the same order. Over this repo's test of it: 183 s to 99 s at the same load.
- Updated dependencies [630d44c]
- Updated dependencies [e65a3b0]
- Updated dependencies [1ce783b]
- Updated dependencies [c095e0e]
- Updated dependencies [e9f29fc]
- Updated dependencies [374b595]
- Updated dependencies [adb7c4d]
- Updated dependencies [053c4a2]
- Updated dependencies [f275d25]
- Updated dependencies [0a8958e]
- Updated dependencies [7e26fd0]
  - @geonosis/base@3.6.0
  - @geonosis/verify@3.6.0
  - @geonosis/doctor@3.6.0
  - @geonosis/ledger@3.6.0
  - @geonosis/lint-parity@3.6.0
  - @geonosis/ratchet@3.6.0
  - @geonosis/release@3.6.0
  - @geonosis/testbed@3.6.0
  - @geonosis/oxlint-plugin-biological-architecture@3.6.0
  - @geonosis/observability@3.6.0
  - @geonosis/review@3.6.0
  - @geonosis/verify-arch@3.6.0
  - @geonosis/visual-diff@3.6.0
  - @geonosis/walk@3.6.0

## 3.5.0

### Minor Changes

- 2cc5f78: An opt-in `i18n` preset: words come from the app's messages, never from literals in code (#137).
  - `no-literal-copy` reports a string literal under a copy name: a text-bearing attribute (`alt`, `title`, `placeholder`, `aria-label`, …), or a prop, key, variable or default named like copy (`label`, `title`, `*Label`, `*Message`, …). Ids, paths, URLs and class maps (`cva`, `tv`, `cn`) are not words.
  - `translator-namespaced` reports a translator called with no namespace. A root-scoped one types every key everywhere, and on a 2,513-key catalogue TypeScript gave up with TS2590.
  - oxlint's own `react/jsx-no-literals`, with `ignoreProps`, judges the text between tags.
  
  `geonosis init` turns on the oxlint plugin a preset's rule names (`react` here). On a Medusa storefront's pre-i18n tree, `jsx-no-literals` alone caught 24% of 1,240 hand-found words, and the copy-name rule covers the attributes, keys and defaults it cannot. `no-literal-copy` leaves tests and stories (`testGlobs`), where the caller hands the words in.
- 2cc5f78: `geonosis update` bumps an npm tree with npm and runs the whole ritual there (#147).
  - `npm install` repins, and `npm ci --ignore-scripts` is the lock proof. `npm install --frozen-lockfile` ignores the flag, so it proved nothing.
  - `npm rebuild` runs the lifecycle scripts `install.allowScripts` names.
  - BY HAND, the doctor, `post-update` and the fast tier follow, as under bun, pnpm and yarn 1.
  - `--runtime npm` names it, and `update --prove` proves every claim under npm too.
  - The release-age gate reads npm's `min-release-age` (days) from the project `.npmrc`, then the user's, or `npm_config_min_release_age`. The refusal offers `--min-release-age=0` and says npm has no exclude list.
  - A refusing lifecycle script is named from npm's `> <package>@<version> <script>` header, and npm's lock-drift message gets the in-place recipe with `npm ci`.
  
  Before, an npm tree got four install lines and nothing else, so a Workers + D1 consumer following them deployed without workflows 0.8.0's claims migration.

### Patch Changes

- 2cc5f78: With no `cf` it can find, the release runner and the doctor now name the version to add (plan 045). That is the newest `cf` past the repo's release-age gate, read from the registry and from `bunfig.toml` or pnpm's `minimumReleaseAge`. Before, the runner said only "the newest past the gate", and the doctor said nothing. The doctor FAILs a Workers repo with no `cf`, in the same sentence the runner refuses with.
  
  `@geonosis/release` now exports the release-age policy reader (`releaseAgePolicyOf`, `youngerThan`, `newestPast`, `gateOf`), moved from the CLI. `@geonosis/base/node` exports `managerOf`, moved from the doctor. The cf and wrangler adapters share one reader of a version's bindings.
- 2cc5f78: `comment-ceiling` ships `capitalized-comments` as `['error', 'always', { ignoreConsecutiveComments: true }]`, and `geonosis init` writes a preset rule with the options the preset ships (#145). Before, the second line of every wrapped comment was a finding: 795 of 846 on a Medusa storefront.
- 2cc5f78: The oxlint counters `geonosis init` writes, and the ratchet's default oxlint command, pass `--report-unused-disable-directives-severity=error`. A disable directive that disables nothing is then an error the ratchet counts (#139).
- 2cc5f78: `geonosis rules`, `init` and `post-update` keep oxfmt off the kit's rule files (#144). Where oxfmt would rewrite them, the directory goes into `ignorePatterns` in a plain-JSON `.oxfmtrc.json`, which oxfmt then reformats in its own shape, or into `.prettierignore` otherwise. oxfmt is asked again, and the line printed says which file changed. Before, the consumer met it as an `oxfmt --check` refusal at commit time, and formatting the files tripped the doctor's rules check. The doctor exports `checkFormatter`.
- 2cc5f78: A repository settles which rule files it receives in `geonosis.json → rules` (#132). `rules.omit` lists files it does not take; a copy the kit wrote is removed. `rules.overrides` maps a file to the repository's own text, written with the kit marker. `update`, `geonosis rules` and the doctor's `rules` check all read both. Before, an edited copy warned and the next update overwrote it. The gate command a rule file names is written in the repository's own package manager, so a bun repository reads `bun run verify`. An override that cannot be read, or that opens with no frontmatter, blocks the write by name.
- 2cc5f78: `create-geonosis` writes the kit's rule files with the gate named in the runtime it scaffolds (`bun run verify` for bun), as the doctor reads them once the lockfile exists. Before, a bun scaffold wrote `pnpm verify`, and after its first install the doctor's `rules` check WARNed that the files differ from what the kit ships. The doctor exports `ruleForManager`, and `kitRuleFiles` takes the manager.
- 2cc5f78: `geonosis update`'s BY HAND holds only work a person has to do. A changesets line that records only a dependency move (`Updated dependencies [sha]` with its `- @geonosis/x@y` lines) is left out, because the update already made that move (#128). The run says how many it left out, and `bump-report.json` keeps them under `dependencyOnly`. A failed bump ends by naming its BY HAND count and where the list is kept (#127): a long FAIL above it no longer hides the list the failure is usually one of. post-update's notes line now says it speaks for the group, and that a moved floor's own changes are listed under BY HAND.
- 2cc5f78: `geonosis update` prints a moved package's changelog entries when the dependency came from a spec that is no version, such as a `file:` tarball (#118); before, it compared nothing and said "not readable". When an entry truly is missing, the line names the file it read.
- 2cc5f78: `geonosis update --dry-run` judges a floor against the commit, as the real run does. A pin the working tree already holds (left by an update that did not finish) is marked `(already in the working tree, not committed)`. A floor already at its target is listed as `unchanged`, no longer as a repin to itself (#108).
- 2cc5f78: `geonosis update` leaves a `file:` pin the author named as written and lists it under `left … — a file the author named, left as written` (#117). It used to repin any `file:` spec of a kit package to the registry version, so a tarball someone pinned on purpose to verify an exact build became the registry's version. A `file:` pin still moves when the last run wrote it from its own `--registry` directory, which the bump report now records resolved.
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [b01150f]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
- Updated dependencies [2cc5f78]
  - @geonosis/release@3.5.0
  - @geonosis/doctor@3.5.0
  - @geonosis/base@3.5.0
  - @geonosis/oxlint-plugin-biological-architecture@3.5.0
  - @geonosis/ledger@3.5.0
  - @geonosis/observability@3.5.0
  - @geonosis/ratchet@3.5.0
  - @geonosis/verify@3.5.0
  - @geonosis/verify-arch@3.5.0
  - @geonosis/lint-parity@3.5.0
  - @geonosis/walk@3.5.0
  - @geonosis/review@3.5.0
  - @geonosis/testbed@3.5.0
  - @geonosis/visual-diff@3.5.0

## 3.4.1

### Patch Changes

- 421c42d: `geonosis update` and `post-update` name a package the kit moved under a subpath of another (D-118). A dependency on `@geonosis/buketi-ui` (or the older `@geonosis/storefront-ui`) is a BY HAND line that names both the dependency and the import prefix: `package.json dependencies @geonosis/buketi-ui → @geonosis/design-kit@<version>: change the dependency to @geonosis/design-kit, and every import specifier @geonosis/buketi-ui/… to @geonosis/design-kit/buketi-ui/…`. The version is the one the release records for `@geonosis/design-kit` in `release-kits.json`, and the old package is never repinned.
- 1ff5238: `geonosis update` runs the post-update of the copy it installed in a workspace that declares the CLI
  when the repository root declares none (#76). It used to resolve the CLI from the root only, fall
  back to the copy running the update (the version being left) and report `OK`. Where the CLI is
  declared and no copy at the target is installed, the step now fails, or is reported as not run when
  the install was skipped, and names `geonosis post-update --from <old>`. The doctor step reads the
  same workspace copy.
- 6584783: `geonosis update` over a tree already on the target says so instead of listing no-op repins (#108). `--dry-run` lists only the pins that move, judged from the commit (a bump not yet committed still shows `1.3.0 → 1.4.0`), and prints `already at <v> — nothing to repin` when none do. A real run ends there, installing nothing, when the last update to that version finished green. After a run that did not finish, which leaves every pin at the target, it runs the steps again and says why: `the last update to <v> did not finish — running its steps again`.
- Updated dependencies [26b31b7]
- Updated dependencies [1425e77]
- Updated dependencies [b347881]
- Updated dependencies [ce98cdc]
- Updated dependencies [354ca55]
  - @geonosis/oxlint-plugin-biological-architecture@3.4.1
  - @geonosis/doctor@3.4.1
  - @geonosis/release@3.4.1
  - @geonosis/base@3.4.1
  - @geonosis/ledger@3.4.1
  - @geonosis/lint-parity@3.4.1
  - @geonosis/observability@3.4.1
  - @geonosis/ratchet@3.4.1
  - @geonosis/review@3.4.1
  - @geonosis/testbed@3.4.1
  - @geonosis/verify@3.4.1
  - @geonosis/verify-arch@3.4.1
  - @geonosis/visual-diff@3.4.1
  - @geonosis/walk@3.4.1

## 3.4.0

### Minor Changes

- 13e1386: `geonosis-doctor` has a `once` check, and `geonosis post-update` a step of the same name, for a repo that adopted the ratchet before `--record` (#51). A scaffolded repo runs `tsc`, `oxlint` and `vitest` once per gate; an existing one kept running each as a step and again inside the counter that reads it, and nothing told it how to switch (one `yarn verify` took 361 s). The check reads `geonosis.json`, the root `package.json` scripts and `geonosis.ratchet.json`, and WARNs where one gate holds a ratchet step that measures and a step that runs the same tool over the same files as a counter with a `command` and no `output`. The line names the step to replace with `geonosis-ratchet --record <counter>` and the `"output"` to add to each counter; `post-update` prints it as a BY HAND line. `recordedOutputOf` and `recordCommandOf` in `@geonosis/base` are where `init`, `create-geonosis` and the check take the recorded file and the record step from.

### Patch Changes

- 22981ae: A kit bin starts on bun when bun is on PATH and falls back to Node when it is not (#52). An npm
  repo with no bun used to get `env: bun: No such file or directory` and exit 127 from a bin that
  needs only the Node its `engines` declares. The shim is now a POSIX shell line ahead of the same
  JavaScript: it `exec`s bun when it finds one, otherwise it says once on stderr that it runs on Node
  and how to get bun, and `exec`s Node. Under `npx`, `npm exec`, `pnpm exec`, `node_modules/.bin` and a
  direct path it adds about 3 ms to a start on bun. Windows stays a non-goal. The doctor's `tool runtime`
  warning no longer says a machine without bun cannot start the bins.
- 6f38053: A BY HAND changeset may name when it applies: `BY HAND (from <3.2.0):` for a repo that came from below 3.2.0, `BY HAND (done by rules, check):` for an action those `geonosis post-update` steps do, both joined by `;`. `post-update` counts an entry `--from` rules out, or whose steps passed earlier in the same run, and does not list it: `1 BY HAND item does not apply from 3.2.0`. An entry with no condition, or one this version cannot read, is listed as before (#77).
- 7492bfa: `geonosis update` and `geonosis explain` read `.oxlintrc.json` the way oxlint does, with comments and
  trailing commas (#90). The lint step of an update took a commented config for one that does not load
  the plugin and reported `ran: false`, passing; it now counts that config's findings. `explain` no
  longer reports a commented config's rules as defaults.
- ce53ff5: `geonosis update` run from inside a workspace package acts on the workspace root (#91). It no longer
  takes the package for the root, finds no lockfile and leaves the other workspaces' pins behind with a
  PASS. The root is the nearest directory above holding `pnpm-workspace.yaml`, a `package.json` with
  `workspaces`, or a lockfile; the run prints `workspace root: <dir>`. With none found and no
  `--runtime`, the refusal names the directories it looked in.
- bf55b0f: `geonosis update` classifies a `yarn.lock` by what it holds (#103): the `# yarn lockfile v1` header
  is yarn 1, a `__metadata:` block is Yarn 2+. An empty `yarn.lock`, or one with neither, is refused
  saying so and naming `yarn install` as the next step. It is no longer called a Yarn 2+ lockfile
  "with a `__metadata` block".
- 6f38053: `geonosis update` counts oxlint findings before and after whenever the bump moves the group, not only when a manifest names `@geonosis/oxlint-plugin-biological-architecture`. A tree that declares only another member and loads the plugin through a hoisted install had the count skipped with `this bump did not move @geonosis/oxlint-plugin-biological-architecture`, and passed over the new plugin's findings.
- 6f38053: `geonosis post-update` and `geonosis update`'s commit body name the release notes as `node_modules/@geonosis/cli/GROUP-CHANGELOG.md` when that link is the copy that ran, and the real path only when it is not. Under pnpm the real path is the virtual store's, whose directory name carries the peers' versions and changes when one of them moves (#78).
- 6f38053: `geonosis post-update` records the kit version it ran for in `.geonosis/post-update.json`, and `geonosis-doctor`'s `rules` check WARNs when that record names an older kit than the one installed, or is missing where `.geonosis/bump-report.json` says an update ran: `` `geonosis post-update --from <version>` has not run here for kit <installed> ``. A correction to 3.3.0, whose CLI README and #44 entry said `geonosis update` runs the copy it installed for an update from any older version: that holds for an update run by 3.3.0 or later. An update run by 3.2.0 or older runs its own steps, with no post-update, no BY HAND lines and no oxlint count, and still says PASS; the doctor that runs after it is the new version's, so it is the one that says so (#76).
- 4086919: `geonosis update` now catches a bump that splits one of the repo's packages into a second snapshot
  (#93). This happens when the kit brings a second version of an optional peer. In a Medusa tree, a
  second `yaml` forked vite, then `@medusajs/framework`, then `core-flows`, so every workflow
  registered twice and the backend refused to boot. The update had said `SKIPPED build — the lockfile
  moved only what this bump repinned`. It now compares pnpm's snapshot keys as well as versions. A
  package whose peers resolve differently counts as moved, the build runs, and the report names it:
  
      @medusajs/core-flows@2.19.0: 1 → 2 snapshots (new peer yaml@2.9.1)
  
  `bump-report.json` carries the splits in `lockSplits`. The kit's own `yaml` range now starts at
  `^2.0.0`, the oldest version its tests pass against, so pnpm reuses the `yaml` a repo already has
  instead of adding a second one.
- Updated dependencies [584cee6]
- Updated dependencies [e7b0be2]
- Updated dependencies [ebb216e]
- Updated dependencies [22981ae]
- Updated dependencies [053eb94]
- Updated dependencies [a88892a]
- Updated dependencies [8ef6383]
- Updated dependencies [7492bfa]
- Updated dependencies [58b5af1]
- Updated dependencies [4e1a611]
- Updated dependencies [8581bd8]
- Updated dependencies [36fdfaf]
- Updated dependencies [13e1386]
- Updated dependencies [77f9a0a]
- Updated dependencies [0758315]
- Updated dependencies [6f38053]
- Updated dependencies [f328b39]
- Updated dependencies [f5287a6]
- Updated dependencies [12ede50]
- Updated dependencies [ab2f233]
- Updated dependencies [97ac4c5]
- Updated dependencies [4086919]
- Updated dependencies [344816b]
  - @geonosis/verify@3.4.0
  - @geonosis/oxlint-plugin-biological-architecture@3.4.0
  - @geonosis/base@3.4.0
  - @geonosis/release@3.4.0
  - @geonosis/lint-parity@3.4.0
  - @geonosis/doctor@3.4.0
  - @geonosis/ledger@3.4.0
  - @geonosis/observability@3.4.0
  - @geonosis/ratchet@3.4.0
  - @geonosis/review@3.4.0
  - @geonosis/testbed@3.4.0
  - @geonosis/verify-arch@3.4.0
  - @geonosis/visual-diff@3.4.0
  - @geonosis/walk@3.4.0

## 3.3.0

### Minor Changes

- fb08b28: The metapackage declares the `geonosis` command itself (#68). pnpm links only the bins of a direct dependency, so with `pnpm add -D geonosis` alone the documented door did not exist; `npx` found it only because npm hoists. `geonosis` now ships `bin/geonosis.mjs`, which runs `@geonosis/cli`'s command through its new `@geonosis/cli/bin` export, and answers exactly as the cli does.

### Patch Changes

- fb08b28: BY HAND: if you updated to 3.2.0 from an older version, run `geonosis rules` once. The updater that ran was your old version's, which has no rules step, so `.claude/rules/geonosis/` was never written and the update still said PASS. `geonosis-doctor` names the same command when the directory is missing.
- fb08b28: `countersFor`, which `geonosis init` and `create-geonosis` write counters with, gives a bun repo one `testFailures` counter per workspace, as it gives a pnpm repo: `bun run --filter <name> test`, reading the `.geonosis/vitest.json` that workspace's test script writes. It returned none for bun, so the report was written and nothing read it, and the doctor warned about it four times over a fresh scaffold.
- fb08b28: The doctor's `tool runtime` advice is the manager's own. Measured on a tree with bun off the PATH: pnpm (11.8.0, 12.10.1) installs what `devEngines.runtime` names and puts it on the PATH of `pnpm exec` and scripts; yarn 1.22.22 and npm 11.13.0 read it for nothing, so the line says `yarn add -D bun@<range>` or `npm install -D bun@<range>`, which links `node_modules/.bin/bun` onto the PATH of `yarn <bin>`, `npm run`, `npm exec` and `npx`. The manager is read from `packageManager`, else the lockfile; where neither names it the line gives all three. A yarn or npm tree that declares bun only in `devEngines` is warned, a bun devDependency in any workspace is OK, and the doctor reads the range from an installed kit's `devEngines.runtime` as well as the `engines.bun` earlier releases declared. `geonosis update` prints the same line as a BY HAND item in its new `runtime` post-update step, and the CLI README carries the table (#52).
- fb08b28: The gates rule every session loads says a tool the ratchet counts runs once, in the fast tier, as `geonosis-ratchet --record <counter>`, and that the ratchet reads the recording and runs nothing; it no longer describes the gate as typecheck, lint and test followed by a ratchet that repeats them. `geonosis rules` and `geonosis update` write the new text.
- fb08b28: `@geonosis/cli` ships `GROUP-CHANGELOG.md`, which every consumer has: the cut writes it once into `packages/cli`, and `geonosis` no longer carries a copy. `geonosis update` prints from it the number of entries between the old and the new version, every entry whose text starts with `BY HAND:`, and the path of the file; the suggested commit body names that path (#33). A changeset whose text starts with `BY HAND:` is how an author marks an action no command can do for the consumer.
- fb08b28: A parse check that did not finish no longer reads as a file that parses (#49). `pre-edit` allows the edit and tells the model, in the hook's `additionalContext`, that the file was not checked; a new `PostToolUse` hook, `post-parse`, registered with `asyncRewake`, then checks the file as written with eight times the budget and wakes the model with the diagnostic when it does not parse, or with the fact that it could not check either. `post-bash` does the same for what a command wrote. Every note a PreToolUse hook allowed with (`no parser here`, `the ledger ran past its budget`) now reaches the model: Claude Code sends the stderr of a hook that exits 0 to the debug log only.
- fb08b28: An install the kit starts tells the packages it installs where it runs. `startedIn(dir)` in `@geonosis/base/node` sets `INIT_CWD` to that directory, and the scaffold's install, `geonosis update`'s commands and the smoke's phases all run through it. A package's install script reads `INIT_CWD`, and lefthook's installs git hooks there: a scaffold or an update started under `pnpm` inherited the caller's `INIT_CWD`, so hooks landed in the repository that ran the command — the kit's own, twice, from its tests.
- fb08b28: The published manifests no longer declare `engines.bun`, which yarn 1 warned about once per installed package (`The engine "bun" appears to be invalid`). A package that starts its bins on bun now names it in `devEngines.runtime`, the same list the kit's root declares; measured on yarn 1.22.22, npm 11.13.0, pnpm 11.8.0 and 12.10.1 and bun 1.4.2, none of them warns on that field in a dependency. A test over every published manifest holds that `engines` has only keys yarn 1 knows and that the list equals the root's, and a yarn 1 install of those manifests prints no engine line (#46).
- fb08b28: A repo `geonosis init` or `create-geonosis` leaves behind runs each tool once per `geonosis-verify full` (#51). Its fast tier is `geonosis-ratchet --record typecheckErrors`, `--record oxlintErrors` and `--record testFailures` (`pnpm exec`, or `bunx` on bun), and the counters name the files they read (`output`), so the ratchet step that follows runs none of them again. The typecheck counter runs the repo's `typecheck` script when it has one (`tsc --noEmit` when it has none); the root test counter prints the runner's own report as well as writing the JSON. `pnpm ratchet` on its own, with nothing recorded, refuses and names the record command, as it does for any counter that reads a recording. `tiersFor` takes `recorded`, the counters a fast step records (all three by default), and `countersFor` takes the repo's script names.
- de03c7c: A repo whose `release.migrations` names the postgres or mikro-orm-ts dialect is told squawk-cli is missing before a gate needs it (#71): the doctor's `release` line FAILs and `geonosis update` prints a BY HAND line, both with the gate's own message and its exact install command. squawk became an optional peer in 3.2.0, so an update from 2.x left it installed until the next reinstall removed it, and the first sign was a ratchet counter that could not measure.
- fb08b28: The Stop hook replays what it already knows about the tree — a fresh red report, the last judged run, a finished background run — before it looks for `geonosis-verify`. It looked first, so a repo where the binary is not on the hook's `PATH` let a turn end over a red report describing that very tree.
- fb08b28: `geonosis update` under a release-age cooldown (pnpm `minimumReleaseAge`, bun `minimumReleaseAge`) checks the third-party packages the kit's packages declare, once the kit's own packages are exempt or the manager's override is in `--install-args`. It stops with exit 2, before writing, and lists each package whose newest release satisfying the declared range is younger than the age: under an exemption that means no old enough release satisfies the range, under an override it means the newest one is young, because the override lifts the age for every package. The README's "Under a release-age cooldown" holds the exemption each manager has, measured: pnpm `minimumReleaseAgeExclude` takes `'geonosis'` and `'@geonosis/*'`, bun `minimumReleaseAgeExcludes` takes exact names and ignores a glob, npm has no per-package exemption. The kit's cut holds what it publishes to the same age: `release:check` refuses a range in a publishable manifest (`dependencies`, `optionalDependencies`, required `peerDependencies`) that no release at least `release.thirdPartyAge` days old (default 7) satisfies, and names the range that would. The published floors of `oxc-parser`, `pixelmatch`, `@modelcontextprotocol/sdk` and six `@radix-ui` packages are lowered to a release that old, with the lockfile still resolving the latest. The doctor's version reader now reads a partial version (`>=19`, `^1`) and an `||` list of such ranges (#67).
- fb08b28: `geonosis update` names a dependency on a package the kit renamed. A tree on `@geonosis/storefront-ui` read "left … its own version line, not this one" and `update PASS`, and stayed on a name the release replaced with `@geonosis/buketi-ui`. The update, `--dry-run` and the commit body now carry a BY HAND item, `package.json dependencies @geonosis/storefront-ui → @geonosis/buketi-ui@1.0.0: change the dependency and every import specifier`, with the version the release records in `release-kits.json`; `bump-report.json` carries it in `byHand`. The new `geonosis post-update` step `replaced` prints the same from the installed copy, so a repo updating from a version that predates this is told too. The renames are one map, `RENAMED_PACKAGES`, which the law-line check (`REPLACED_BY`) now includes, and a test holds that each new name is a package this workspace publishes (#44).
- fb08b28: `geonosis update` says why the build step did not run in one sentence (no build tier declared) and reports what the lockfile moved beyond the repinned packages apart, in `lockMoves` of the bump report and in a `lockfile` line (#35). A package is the kit's own dependency when it is reachable from a repinned package in the lockfile's dependency graph; a platform family folds into the package whose `optionalDependencies` list it (`oxc-parser ×22`); a package is named only when a manifest of the repo declares it, and the rest is counted. The lockfile is read for pnpm, bun and yarn 1.
- fb08b28: `geonosis update` hands its post-install work to the copy of `@geonosis/cli` it just installed: it runs that copy's `geonosis post-update --from <version>`, and falls back to its `geonosis rules` for a version that predates it, so a step a later release adds reaches a repo updating from any older version, from that release on. Until now the code that ran was the old version's: updating to 3.2.0 from 2.12.0 reported PASS and never wrote `.claude/rules/geonosis/` (#31). `post-update` writes the rule files, checks them with the doctor's `rules` check and exits 1 when they are not what the kit ships, so an update cannot report PASS where the doctor would warn about them. The report names the step `post-update`, in place of `rules`. The doctor's `rules` advice names `geonosis rules` first and `geonosis update --to <version>` only when the copies were written by a newer kit than the installed one; `compareVersions` moves from the CLI to `@geonosis/doctor`.
- fb08b28: `geonosis update` runs oxlint over the tree when the bump moves `@geonosis/oxlint-plugin-biological-architecture`, whatever the repo's `fast` tier runs. It counts the errors of each `.oxlintrc.json` that loads the plugin before the repin and after the install, and an error the old plugin did not report FAILs the update with a BY HAND item naming the count and the rules; a run of the same bump again keeps the count the first run measured, so a tree still red is not passed the second time. The update said `PASS` over 13 new findings in a tree whose `fast` tier ran ESLint only (#45).
- fb08b28: `geonosis update` and `update --dry-run` stop with exit 2, before writing anything, when a package they would install is younger than the release age the consumer's manager holds back (#38). bun's is `[install] minimumReleaseAge` (seconds) in the project's `bunfig.toml`, `$XDG_CONFIG_HOME/.bunfig.toml` or `~/.bunfig.toml`; pnpm's is `minimumReleaseAge` (minutes), read with `pnpm config get`. The message names the policy and the file it is set in, each held release's publish time from the registry and the date it becomes installable, and the two ways the user may choose to install it now: `--install-args "--minimum-release-age 0"` (bun) or `--install-args "--config.minimumReleaseAge=0"` (pnpm), or the manager's exclude list (`minimumReleaseAgeExcludes`, exact names, in bunfig; `minimumReleaseAgeExclude` in `pnpm-workspace.yaml`). The kit never overrides the policy; an override already in `--install-args` is the user's choice and the check steps aside. Packages the exclude list names are not held. npm's `min-release-age` is not read: neither bun 1.4.2 nor pnpm 11.8.0 applies it (measured), and `update` never installs with npm.
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [17dc880]
- Updated dependencies [4ea788c]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [de03c7c]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
- Updated dependencies [fb08b28]
  - @geonosis/doctor@3.3.0
  - @geonosis/release@3.3.0
  - @geonosis/verify@3.3.0
  - @geonosis/ledger@3.3.0
  - @geonosis/base@3.3.0
  - @geonosis/oxlint-plugin-biological-architecture@3.3.0
  - @geonosis/testbed@3.3.0
  - @geonosis/observability@3.3.0
  - @geonosis/ratchet@3.3.0
  - @geonosis/lint-parity@3.3.0
  - @geonosis/review@3.3.0
  - @geonosis/verify-arch@3.3.0
  - @geonosis/visual-diff@3.3.0
  - @geonosis/walk@3.3.0

## 3.2.0

### Minor Changes

- dd5f57a: `geonosis update --floors latest` or `--floor <pkg>@<v>` works without `--to`: the group stays at the one version every manifest carries, only the floors move, and the output says `group unchanged at <v>`. A group split across versions is refused and `--to` settles it. A dry run prints a floor already at its target as `(already here)`, a plain `--to` names each own-line package that is behind its line, and a move to an older version is flagged `DOWNGRADE` and reads the changelog entries it undoes instead of calling the older entry unreadable.
  `geonosis portfolio` prints one row per consumer named in `geonosis.json → portfolio.consumers`, read off the artifact that consumer's CI uploaded: version, lag in days off the registry's publish dates, last green tier, lines the last bump deleted. It exits 2 and prints no row when an artifact is missing or will not parse.
  `install.allowScripts` in `geonosis.json` lists package names (`@embedded-postgres/*`) whose lifecycle scripts run after the frozen install's `--ignore-scripts`, with `pnpm rebuild` or `bun pm trust`.
  `sync` refuses (exit 2) over a `geonosis.json` it cannot parse. `init` reads `geonosis.json → stack`: for a language or linter oxlint does not read it writes no `.oxlintrc.json` and no oxlint, tsc or oxfmt counter, and refuses an unreadable config. The MCP server's skew check falls back to the lockfile's resolved version and reports `UNJUDGED` when nothing answers; `update`'s restart line looks in `~/.claude.json` (user and local scope), an installed plugin's `.mcp.json` and Cursor's `mcp.json` as well as `.mcp.json`, and names which one it found.
- 9b1ce78: `geonosis init` and `geonosis update` copy the kit's rule files into `.claude/rules/geonosis/` (also `geonosis rules` alone), each with a `# geonosis-kit <version>` line directly under its opening `---`, removing marked files the kit no longer ships and leaving files a user added; `update` runs the copy it just installed, so the files are the new version's. Copies, because Claude Code loads a symlink out of the repo only after approval and then only the rules with no `paths` list; a `.claude/rules/geonosis` that is a symlink is refused, never written through. `geonosis-doctor` gains a `rules` check that warns when the directory is missing in a kit repo, or a copy differs from what the installed kit ships, naming the file and `geonosis update`.
- a4a7bba: `@geonosis/cli` exports `lawSummary({ name, runtime, marketplace })` and `LAW_SUMMARY_TITLES`: the short-form law a scaffolded repo starts with, built in one place, and held by a test against the laws of this repo's own `LAW.md` (every title present, in the same order). `create-geonosis` writes its `LAW.md` from it; the text is unchanged. `geonosis-ledger sync --target agents-md` adds a "Style, in the code these laws produce" section to the generated `AGENTS.md`: the terse-output sentence and the comments law, the same text the plugin's skills and agents carry, exported as `TERSE_OUTPUT_LAW` and `COMMENTS_LAW`.
- deef511: A repo whose `geonosis.json → stack` is not TypeScript passes the doctor with a SKIP that names the language, and gets the method scaffolded without the TypeScript stack. `geonosis-doctor` SKIPs `exercised` as it already did `loaded` (`stack.language is "py"`, so there is no oxlint rule for a corpus to be asked to reach), and `drift` SKIPs, instead of warning "no manifest declares it", a `geonosis.json` block of a kit package in a repo with no package manifest at all; the doctor no longer refuses a tree with no `package.json` and no `.oxlintrc.json` as "nothing here to examine" when `geonosis.json` declares a stack oxlint does not read. `stack` gains `extensions` (`.py .pyi`), the files `stack.format` and `stack.parse` own: with it, the plugin formats only those with `stack.format`, and `pre-edit` and `post-bash` parse them with `stack.parse` (exit non-zero is a parse error; a parser that cannot run says nothing). `stack.parse` without `extensions` applies to no file. A repo with no `stack` behaves as before.
  `create-geonosis <dir> --language py` writes a uv project (`pyproject.toml`, a package, a test), `geonosis.json` with the stack, three `fast` steps with plants and a `full` tier that proves and runs the ratchet (`ruff format --check`, `ruff check`, `pytest`), `LAW.md` from the new `pythonLawSummary` of `@geonosis/cli`, the two language-neutral counters and their baseline, the kit's rule files, `.claude/settings.json` and a CI workflow; it refuses `--runtime`, `--backend`, `--ui`, `--domains`, `--medusa`, `--themekit`, `--brand`, `--kit`, `--presets` and `--check` by name.
- 58eaf3a: `geonosis update` bumps a yarn 1 tree: it reads `yarn.lock` with `@yarnpkg/lockfile`, installs with yarn and leaves `yarn install --frozen-lockfile` clean, and `--runtime yarn` names it where no lockfile does. It refuses with exit 2, before writing, when the `yarn` that runs is not yarn 1 (pin `"packageManager": "yarn@1.22.22"`). A `package-lock.json` or a Yarn 2+ `yarn.lock` is refused with exit 2 and the commands that manager's consumer runs instead. `--dry-run` now refuses what the real run refuses. A client kit (`@geonosis/<client>-ui`) moves with the release, to the version the target `@geonosis/cli` records in its published `release-kits.json`. `update --prove` proves the yarn 1 path and the kit, and now FAILS when a manager is not on the machine unless `--skip <manager>` names it.

### Patch Changes

- f5632b7: New `@geonosis/base`: the zero-dependency bottom of the method, holding what packages used to copy. `@geonosis/base` is `isRecord`, `isStringList`, `stringsOf`, the error text helpers and the markdown readers (`headingsOf`, `sectionUnder`, `fencedLines`, `titleOf`), safe in a browser or a Worker; `@geonosis/base/node` is `packageRootFrom`, `versionOf` and `isDirectory`; `@geonosis/base/bin-harness` is `binRunner(runtime)` for running a package's bin in a test, with `GIT_ISOLATED` for a bin that shells to git.
  `cli`, `create-geonosis`, `ledger`, `mcp`, `observability`, `rails`, `release`, `review`, `themekit`, `verify`, `verify-arch` and `walk` import the guards from it instead of carrying their own; their behaviour is unchanged and each now installs `@geonosis/base`, which a consumer never declares.
  The ratchet keeps its own copies: the build runs on its source before any package exists, so nothing it imports may be a package the build produces.
- f5632b7: `--registry <path>` is told apart from a URL by a missing path only (ENOENT, ENOTDIR); any other filesystem error, and any error but a syntax error while reading a packed `package.json`, is rethrown instead of read as "not a registry directory" or "not a package".
- 58eaf3a: `geonosis explain constructor` (or `toString`, `hasOwnProperty`, `__proto__`) is refused as a name nothing here decides, instead of crashing on the property every object inherits; a `geonosis.ratchet.json` whose `counters` hold a `null` or are not a list no longer crashes it either.
- 58eaf3a: `geonosis init` refuses, writing nothing, when a kept `geonosis.ratchet.json` points its baseline outside the repo; `rulesFor` names a preset nobody ships (`no preset called …`) in place of a `TypeError` on `undefined.rules`.
- 58eaf3a: `geonosis sync` reads a `geonosis.json` `law` block key by key: a `file` that is not a string, a `maxLines` that is not a number or a `copy` that is not a boolean is no declaration, where a numeric `file` crashed the run on `join`.
- 58eaf3a: `geonosis skills lock` and `audit` refuse a `skills-lock.json` that is not JSON or holds no `skills` block, naming the file, in place of a `TypeError` from the middle of the run; relocking keeps every other key a previous lock recorded for a skill and for the lock itself instead of rewriting each entry down to four.
- 58eaf3a: `geonosis update` repins a manifest with its own line endings and its own last line: a CRLF file stays CRLF and a file with no final newline gets none, so a bump is a version diff and not a rewrite of every line.
- Updated dependencies [58eaf3a]
- Updated dependencies [dd5f57a]
- Updated dependencies [deef511]
- Updated dependencies [dd5f57a]
- Updated dependencies [f5632b7]
- Updated dependencies [a4a7bba]
- Updated dependencies [9b1ce78]
- Updated dependencies [5404b2a]
- Updated dependencies [56c920e]
- Updated dependencies [dd5f57a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [9b1ce78]
- Updated dependencies [a4a7bba]
- Updated dependencies [dd5f57a]
- Updated dependencies [dd5f57a]
- Updated dependencies [16198a4]
- Updated dependencies [a4a7bba]
- Updated dependencies [a4a7bba]
- Updated dependencies [a4a7bba]
- Updated dependencies [a4a7bba]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [f5632b7]
- Updated dependencies [dd5f57a]
- Updated dependencies [deef511]
- Updated dependencies [dd5f57a]
- Updated dependencies [dd5f57a]
- Updated dependencies [58eaf3a]
- Updated dependencies [dd5f57a]
- Updated dependencies [a4a7bba]
- Updated dependencies [58eaf3a]
- Updated dependencies [58eaf3a]
- Updated dependencies [f5632b7]
- Updated dependencies [a4a7bba]
- Updated dependencies [f5632b7]
- Updated dependencies [deef511]
- Updated dependencies [deef511]
- Updated dependencies [deef511]
- Updated dependencies [deef511]
- Updated dependencies [dd5f57a]
- Updated dependencies [a4a7bba]
- Updated dependencies [f5632b7]
- Updated dependencies [deef511]
- Updated dependencies [dd5f57a]
- Updated dependencies [67aefe3]
- Updated dependencies [67aefe3]
  - @geonosis/doctor@3.2.0
  - @geonosis/release@3.2.0
  - @geonosis/verify@3.2.0
  - @geonosis/ratchet@3.2.0
  - @geonosis/base@3.2.0
  - @geonosis/ledger@3.2.0
  - @geonosis/observability@3.2.0
  - @geonosis/review@3.2.0
  - @geonosis/verify-arch@3.2.0
  - @geonosis/walk@3.2.0
  - @geonosis/lint-parity@3.2.0
  - @geonosis/oxlint-plugin-biological-architecture@3.2.0
  - @geonosis/testbed@3.2.0
  - @geonosis/visual-diff@3.2.0

## 3.1.0

### Patch Changes

- Updated dependencies [bd82a2e]
- Updated dependencies [de32d20]
- Updated dependencies [27d169d]
  - @geonosis/ratchet@3.1.0
  - @geonosis/ledger@3.1.0
  - @geonosis/oxlint-plugin-biological-architecture@3.1.0
  - @geonosis/doctor@3.1.0
  - @geonosis/lint-parity@3.1.0
  - @geonosis/release@3.1.0
  - @geonosis/verify@3.1.0
  - @geonosis/observability@3.1.0
  - @geonosis/review@3.1.0
  - @geonosis/testbed@3.1.0
  - @geonosis/verify-arch@3.1.0
  - @geonosis/visual-diff@3.1.0
  - @geonosis/walk@3.1.0

## 3.0.0

### Patch Changes

- 1e38e4e: `geonosis-themekit`, `geonosis-rails` and `geonosis-evals` read their arguments with `node:util`'s `parseArgs`. A flag one does not know is refused by name, exit 2, where the hand-written readers ignored it and ran without it; a flag given twice keeps its last value in all three (evals kept the first). `geonosis-evals compare --tolerance x=0.1 a.json b.json` reads `a.json` and `b.json` as the scores: the old reader took the tolerance's value for the first score file. `geonosis-ratchet` and `geonosis-verify`, which already refused what they did not know, read their flags the same way; verify still refuses a flag that belongs to another of its commands. `geonosis-doctor` reads its flags with `parseArgs` too, its optional `--baseline-against` ref through the parser's tokens. `@geonosis/ledger`'s exported `parseArgs(argv, valued, switches)` is `node:util`'s underneath and takes the switches it accepts, refusing an undeclared one and a valued flag followed by another flag (`--note --plan 3` used to store `--plan` as the note); `rejectUnknownSwitches` is gone. `geonosis-walk`, `geonosis-review` and `geonosis-lint-parity` parse the same way; parity keeps its own words for a bare `--corpus` or `--expect-changed`. `geonosis-observability`, `geonosis-verify-arch`, `geonosis-testbed` and `geonosis-visual-diff` follow; the last two used to accept a flag they did not know (testbed ignored it, visual-diff read it as a switch) and now refuse it. `@geonosis/release`'s exported `parseArgs` keeps its `Parsed` shape over `node:util`'s. `@geonosis/cli`'s `parseArgv` and `create-geonosis`'s `parseArgs` are built on it too, keeping their own refusals; `parseArgv` now refuses a valued flag followed by another flag instead of taking that flag as its value.
- Updated dependencies [0f272e2]
- Updated dependencies [1e38e4e]
- Updated dependencies [5560282]
- Updated dependencies [feb9983]
- Updated dependencies [559c117]
- Updated dependencies [7d381dd]
- Updated dependencies [9b91c6a]
- Updated dependencies [a6006d7]
- Updated dependencies [fcd6798]
- Updated dependencies [53c995b]
- Updated dependencies [30ae83d]
- Updated dependencies [59c575f]
- Updated dependencies [237a353]
- Updated dependencies [670f7c1]
- Updated dependencies [7fda2db]
  - @geonosis/doctor@3.0.0
  - @geonosis/ratchet@3.0.0
  - @geonosis/verify@3.0.0
  - @geonosis/ledger@3.0.0
  - @geonosis/walk@3.0.0
  - @geonosis/review@3.0.0
  - @geonosis/lint-parity@3.0.0
  - @geonosis/observability@3.0.0
  - @geonosis/testbed@3.0.0
  - @geonosis/verify-arch@3.0.0
  - @geonosis/visual-diff@3.0.0
  - @geonosis/release@3.0.0
  - @geonosis/oxlint-plugin-biological-architecture@3.0.0

## 2.13.0

### Patch Changes

- f422aea: Every bin is an eleven-line shim that loads its `dist`. The stale-build guard it carried in all eighteen copies now lives once in the kit's own tree and loads only there, so an installed package runs no guard code at all.
- Updated dependencies [f422aea]
- Updated dependencies [f422aea]
- Updated dependencies [f422aea]
- Updated dependencies [f422aea]
- Updated dependencies [f422aea]
- Updated dependencies [f422aea]
- Updated dependencies [ae995df]
- Updated dependencies [f422aea]
  - @geonosis/verify@2.13.0
  - @geonosis/ratchet@2.13.0
  - @geonosis/release@2.13.0
  - @geonosis/doctor@2.13.0
  - @geonosis/ledger@2.13.0
  - @geonosis/lint-parity@2.13.0
  - @geonosis/oxlint-plugin-biological-architecture@2.13.0
  - @geonosis/observability@2.13.0
  - @geonosis/review@2.13.0
  - @geonosis/testbed@2.13.0
  - @geonosis/verify-arch@2.13.0
  - @geonosis/visual-diff@2.13.0
  - @geonosis/walk@2.13.0

## 2.12.0

### Patch Changes

- Updated dependencies [7c3879a]
  - @geonosis/ratchet@2.12.0
  - @geonosis/doctor@2.12.0
  - @geonosis/ledger@2.12.0
  - @geonosis/lint-parity@2.12.0
  - @geonosis/release@2.12.0
  - @geonosis/verify@2.12.0
  - @geonosis/observability@2.12.0
  - @geonosis/oxlint-plugin-biological-architecture@2.12.0
  - @geonosis/review@2.12.0
  - @geonosis/testbed@2.12.0
  - @geonosis/verify-arch@2.12.0
  - @geonosis/visual-diff@2.12.0
  - @geonosis/walk@2.12.0

## 2.11.1

### Patch Changes

- 08611c4: Every child whose output a tool captures is read whole, where Node's default silently cut it at 1 MiB and killed the child.
  
  - **Real bug:** a gate step printing more than 1 MiB read as failed to `geonosis-verify`.
  - **At risk:** the smoke's `pnpm pack --json`, `discover`'s oxlint run, and the git, squawk and oxfmt reads could hit the same cap.
  
  `--require-work` also counts a file that a test runs through a helper naming its bin, not only through the test itself.
- Updated dependencies [d3fc711]
- Updated dependencies [e67fc1b]
- Updated dependencies [1d0438d]
- Updated dependencies [08611c4]
- Updated dependencies [74312ef]
  - @geonosis/oxlint-plugin-biological-architecture@2.11.1
  - @geonosis/ratchet@2.11.1
  - @geonosis/ledger@2.11.1
  - @geonosis/verify@2.11.1
  - @geonosis/release@2.11.1
  - @geonosis/doctor@2.11.1
  - @geonosis/observability@2.11.1
  - @geonosis/lint-parity@2.11.1
  - @geonosis/review@2.11.1
  - @geonosis/testbed@2.11.1
  - @geonosis/verify-arch@2.11.1
  - @geonosis/visual-diff@2.11.1
  - @geonosis/walk@2.11.1

## 2.11.0

### Minor Changes

- 0f99e26: An enabled rule missing its option reports ONE finding a run instead of throwing (D-084), and the
  five rules that chose their files from paths compiled in read them from an option (#12).
  
  **The posture.** Up to 2.10.0 a rule enabled without an option it requires threw from `create()`.
  Measured: the throw erased every other finding in the file it surfaced on, and rendered under
  `--format=unix` as `:0:0:  [Warning]` naming nothing. It is a finding now — attributable, counted by
  the ratchet, neighbours intact — reported once per run on the first file oxlint constructs the rule
  for, with the same `biological-architecture/<rule> requires option \`<option>\`.` header. Nothing the
  plugin exports throws for a missing option. Expect exactly one new finding per bare rule per run
  where a run used to be refused whole.
  
  **#12 — four rules now REQUIRE a tree option; every config extending `backend-workflows` or
  `tenant-scoping` must name it or gets the one finding above:**
  
  - `tables-declare-their-plane` requires `schema` (a regex over the filename: the schema tree);
    `control/` and `tenant/` are read under it.
  - `tenant-tables-carry-org-id` requires `tenant` (a regex: the tenant-plane schema tree).
  - `queries-require-org-scope` requires `queries` (a regex: the query modules).
  - `dialect-through-the-seam` requires `seam` (regex sources: the files that may name a dialect);
    `exempt` defaults to the test paths (`__tests__/`, `.test.`, `.spec.`) — a repo whose test helpers
    live elsewhere (`testing/`) names them.
  
  `no-d1-transaction` takes `transacts` and `except` (regex sources), both defaulting to nothing: the
  plane the rule exempted was one repo's, and a D1-only repo has no plane to exempt. Expect new
  findings on every `db.transaction()` that used to sit inside `/packages/db/(src|testing)/`.
  
  One consumer's values, verbatim, are in `proofs/issue-12-and-option-posture-2026-09-18.md`.
  
  `@geonosis/doctor`: `missingOptionOf` hears a refusal a rule reports as well as one it throws;
  `exercised` no longer counts a bare rule's refusal finding as reach — it is a FAIL naming the option.
  `@geonosis/cli`: `optionsNeededBy` reads through the same reader, so `init` still leaves those rules
  out and names them.
  
  REFUSAL-IN-MINOR: **tables-declare-their-plane, tenant-tables-carry-org-id, queries-require-org-scope and dialect-through-the-seam** refuse a bare run where they did not at 2.10.0, which is a break and
  would normally want a major. It ships in a minor by the owner's ruling of 2026-09-19, on a measured
  basis: every consumer pins this kit EXACTLY — three consumers, at 2.10.0, 2.6.1 and 2.10.0, no
  caret anywhere — so nothing auto-upgrades and the version number protects nobody here. The warning
  lives in this changelog instead, and the two consumers that could be reached were told directly
  before the cut. The third is three releases behind; it is the one that must be told by hand.
- 0f99e26: `geonosis sync --targets cursor` gives each file a skill points at its own Cursor rule, beside the
  skill's own: a skill is a folder, and `geonosis-code` is now an index with one file per preset, read
  only where the preset is enabled. A projection of `SKILL.md` alone would drop every shape.

### Patch Changes

- 0f99e26: Every bin's stale-build guard now sees the workspace dependencies its build read. A `dist`
  current against its own `src` could still have been built against an older dependency's `dist` —
  literally, where tsup inlined a workspace devDependency into it — and a dependency whose own `src`
  had moved past its `dist` was read stale by every bin above it; the guard answered "current" for
  both. Now each shim holds every `workspace:` dependency, transitively, to the same reading as its
  own package (never built, stale against its src, current), and refuses when this `dist` is older
  than a dependency's — by content, so a dependency rebuilt to the same bytes with
  `--force --filter` is the same build and does not poison the tree. Unknown is still stale: the
  first run over a tree where a dependency was rebuilt alone, before any record, refuses once and
  names `--force --filter=<this package>`. Only a checkout with `src/` beside `dist/` sees any of
  this; the published package ships no `src/` and the guard is skipped. Measured: within noise for a
  bin with one dependency, +8 ms for `geonosis`, which walks fourteen.
- 0f99e26: Every bin's stale-build guard decides, and never throws. The digest guard's refusal read
  `package.json` to name `pnpm build --force --filter=<name>`; over a checkout with no manifest
  beside the bin it ended with exit 1 and a `node:fs` frame instead of exit 2 and a sentence. The
  name is now a courtesy the refusal does without. The contract, stated: a source newer by mtime whose
  content the bin saw beside a current dist is not stale; one whose content differs is, and the
  refusal names the fix; one the bin has no record for is stale — unknown is stale; a missing dist is
  "never built". Each is exit 2 with a sentence. Only a checkout with `src/` beside `dist/` sees any
  of this; the published package ships no `src/` and the guard is skipped.
- 0f99e26: The CLI reports what it read, not what it assumed.
  
  - `geonosis explain <counter>` reads the baseline from the file `geonosis.ratchet.json` names; a
    repo with `"baseline": "scripts/debt.json"` was told its counter had none.
  - `geonosis discover` refuses when oxlint could not load the config. oxlint exits 1 for a plugin it
    cannot load as it does for a finding, and the tree was reported as having no finding.
  - `geonosis update --dry-run` says a floor's changelog could not be fetched, with the URL and the
    reason, instead of saying the package ships none.
  - `geonosis init` no longer writes `"command": "true"` for `disabledCiJobs` and
    `packagesWithoutTypecheck`; neither counter runs a command. Its output names the baseline file it
    wrote.
  - The BY HAND block, the usage text and the README say what an unconfigured rule does since D-084:
    it judges nothing and says so once a run. The README lists `update`, `explain` and `release`.
- 0f99e26: `geonosis init` refuses over a root `package.json` that does not parse, naming it. It read the manifest's scripts as none and wrote gate tiers without them.
- 0f99e26: `geonosis update` fails its verify step over a `geonosis.json` that does not parse, naming the file. It read an unreadable file as one declaring no tier, and reported the bump PASS over a tree whose gates it never ran.
- 0f99e26: Four bugs a consumer filed against 2.10.0 (#13–#16).
  
  `no-void-port` takes `engineCallbacks` — regexes over an exported alias name, empty by default —
  so a workflow-hook check the engine catches (`HookCheck<TInput> = (input, ctx) => Promise<void>`)
  can be named as not a port; a `Result` there would never be read.
  
  `geonosis-doctor`: the Claude-plugin train is held only against the install that LOADS at the
  doctored root (user scope, or a project scope naming that root), never another repo's; the
  spare-declaration question reads the script files scripts and hooks run, CI workflows and
  `geonosis.json` tiers, sees a bin quoted as an argv string, and says nothing about a package with
  no bin. Expect four fewer WARNs on a root whose gate lives in a `.mjs`.
  
  `geonosis-mcp`: a server started before an in-session `geonosis update` refuses every call naming
  the version it is running, the version the repo now has, and the restart (`/mcp` → reconnect) —
  never the install. `geonosis update` ends by saying so where `.mcp.json` names a `geonosis` server.
- 0f99e26: The kit names no consumer. Docs, doc comments and messages describe the repos a pattern was measured in by their stack (a Medusa storefront, a Workers + D1 app, a Mercur v1 marketplace). Example configs are named the same way: `examples/medusa-storefront.*.json`, `examples/workers-app.*.json`. No behaviour changes.
- 0f99e26: Three defects a consumer measured against 2.10.0 (#17, #18, #19) and one this tree found.
  
  `geonosis-ratchet`: a counter's command that crashed is never a reading (#18). Every counter that
  runs a tool declares the exit codes it reads — `[0, 1]` for a linter, `[0, 1, 2]` for tsc, `[0]`
  where nothing is declared — and an entry may override them with `okExits`. Any other exit refuses
  the counter, and so does a non-zero exit whose output is a Node stack trace, whatever the set says.
  Before, a counter script that threw had its trace's line numbers summed as findings: reported as a
  regression when they summed high, and BANKED as a shrink when they summed low — the baseline
  rewritten to a number no measurement produced. Expect `CANNOT MEASURE` where a command exits with
  a code its tool never uses for findings; declare `okExits` on that entry if the tool is right.
  
  `geonosis-doctor`, `geonosis`, `geonosis-release`, `geonosis-observability`: the bins set
  `process.exitCode` and let the runtime drain instead of calling `process.exit()` after writing the
  report (#17). Through a pipe on macOS, anything past 64 KiB was dropped with a clean exit code —
  the doctor delivered 65,536 of 323,665 bytes, `release migrations` 50 locations for 51 warnings.
  
  The Claude plugin's Stop hook (#19): a cached fast-tier report is fresh only while the tree it was
  judged over is still here, gitignored artifacts included — deleting a `playwright-report/` the
  lint step had read now relaunches the tier instead of replaying the stale FAIL for ever. And a
  replayed report says how many of its steps never ran, red or green.
- 0f99e26: Two defects the gates found (rows 576, 577) and five frictions one consumer measured (#1, #2, #5,
  #9, #10), plus the stale-build guard every adopter-from-a-checkout hits.
  
  `geonosis-ratchet`: a red test suite is a reading again (row 576). The #18 crash detector ran
  before a counter's `okExits` and refused every red suite — an `AssertionError` over frames, and
  Node's trailer whenever a failing assertion quoted the child it ran — so `testFailures` refused
  at the one moment it had something to say. A crash is now a STREAM whose last lines are a trace
  (the runtime's trailer, or an error line over at-frames with nothing after), judged at any exit
  code; a runner that quoted a trace and printed its summary after it is read. `node crash.mjs`
  still refuses, and so does the same crash hidden behind a pipe's exit 0. And a file-set counter
  names its offenders (#2): `unformattedFiles` cites the files it named, most recently modified
  first, under a line that says so. The `evidence` hook receives `cwd`, and the report keeps a
  counter's FIRST ten citations rather than the tail.
  
  `geonosis-doctor`: an `exercised` line per config lists the rules the plugin ships that the
  config never mentions — absent, told apart from off (#5) — so a release's new rules are a list,
  not an audit. Expect one new WARN on any config that leaves shipped rules unnamed. A `drift`
  line reports a `pnpm` block in `package.json` that pnpm 11 does not read (#1): FAIL under a pin
  of 11 or later, with the keys, the new home and the install repair. The observability age and
  probe questions SKIP for a sink that reaches nothing (#10) instead of measuring how recently a
  developer ran the app.
  
  `geonosis`: the update's restart line and the MCP skew refusal say the bins in
  `node_modules/.bin` are already the new release (#9).
  
  Every kit bin's stale-build guard compares CONTENT, not only mtime: a checkout rewrites `src`
  with the same content and the next `pnpm build` is a cache hit that leaves the current `dist`
  untouched, so every bin refused with "run pnpm build" — the action that had just changed
  nothing. Each shim keeps a digest of `src` from the last run that found `dist` current; a real
  change still refuses, and the refusal names `pnpm build --force --filter=<package>`.
- 0f99e26: `geonosis update`'s seam figure is measured from where the branch left the default one. It diffed
  against the default branch's tip, so every line that branch changed in a seam file after the
  adopter branched off was counted as the adopter's: a seam main had grown by fifty lines read as fifty
  more deleted.
- 0f99e26: `geonosis skills lock` refuses when two different skills share a name across `skills/`,
  `plugin/skills/` and `.claude/skills/`, naming both paths; it pinned whichever came last. `skills
  audit` fails on the same clash by name instead of reporting a hash drift on one of the two. A skill
  copied byte for byte into a second root is one skill, as before.
- 0f99e26: Every order a tool writes, compares or applies — generated files, migration order, listings, cursors — sorts with the `en-US` collation, named rather than inherited from the machine. On an `en-US` machine nothing moves; on one set to another language (Estonian sorts `z` before `t`) the output is now the same one.
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [c84e4a0]
- Updated dependencies [7db8a78]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [57d794d]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [ad81ece]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [a9eb439]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
- Updated dependencies [0f99e26]
  - @geonosis/ratchet@2.11.0
  - @geonosis/doctor@2.11.0
  - @geonosis/ledger@2.11.0
  - @geonosis/lint-parity@2.11.0
  - @geonosis/observability@2.11.0
  - @geonosis/release@2.11.0
  - @geonosis/review@2.11.0
  - @geonosis/testbed@2.11.0
  - @geonosis/verify-arch@2.11.0
  - @geonosis/verify@2.11.0
  - @geonosis/visual-diff@2.11.0
  - @geonosis/walk@2.11.0
  - @geonosis/oxlint-plugin-biological-architecture@2.11.0

## 2.10.0

### Patch Changes

- Updated dependencies [3863c79]
- Updated dependencies [4c240df]
  - @geonosis/lint-parity@2.10.0
  - @geonosis/oxlint-plugin-biological-architecture@2.10.0
  - @geonosis/doctor@2.10.0
  - @geonosis/ledger@2.10.0
  - @geonosis/observability@2.10.0
  - @geonosis/ratchet@2.10.0
  - @geonosis/release@2.10.0
  - @geonosis/review@2.10.0
  - @geonosis/testbed@2.10.0
  - @geonosis/verify@2.10.0
  - @geonosis/verify-arch@2.10.0
  - @geonosis/visual-diff@2.10.0
  - @geonosis/walk@2.10.0

## 2.9.0

### Patch Changes

- Updated dependencies [e35392e]
  - @geonosis/oxlint-plugin-biological-architecture@2.9.0
  - @geonosis/doctor@2.9.0
  - @geonosis/ledger@2.9.0
  - @geonosis/lint-parity@2.9.0
  - @geonosis/observability@2.9.0
  - @geonosis/ratchet@2.9.0
  - @geonosis/release@2.9.0
  - @geonosis/review@2.9.0
  - @geonosis/testbed@2.9.0
  - @geonosis/verify@2.9.0
  - @geonosis/verify-arch@2.9.0
  - @geonosis/visual-diff@2.9.0
  - @geonosis/walk@2.9.0

## 2.8.0

### Patch Changes

- Updated dependencies [e880a6c]
  - @geonosis/oxlint-plugin-biological-architecture@2.8.0
  - @geonosis/doctor@2.8.0
  - @geonosis/ledger@2.8.0
  - @geonosis/lint-parity@2.8.0
  - @geonosis/observability@2.8.0
  - @geonosis/ratchet@2.8.0
  - @geonosis/release@2.8.0
  - @geonosis/review@2.8.0
  - @geonosis/testbed@2.8.0
  - @geonosis/verify@2.8.0
  - @geonosis/verify-arch@2.8.0
  - @geonosis/visual-diff@2.8.0
  - @geonosis/walk@2.8.0

## 2.7.0

### Patch Changes

- d90986b: `geonosis update` names the seam globs that match no file. `adoption.seams` is measured with
  `git diff --numstat` over the globs, and a glob whose file was deleted and never undeclared reads as
  `0 deleted, 0 added` — during.day carried three such globs for a month and every bump report said
  the seams had not moved. `SeamMovement` gains `unmatched` (the globs no tracked or on-disk file
  answers to) and the report prints a `WARN seams: N glob(s) match nothing — …` line naming them.
- d90986b: `geonosis-verify` tells a step that RAN NOTHING from one that passed. A step that exits 0 saying so
  — turbo's "No tasks were executed as part of this run" / "Running x in 0 packages", vitest's "No
  test files found", bun's "Ran 0 tests", or any command that prints `SKIP …` on a line of its own —
  is printed `idle` instead of `ok`, carries `idle: true` in the gate report, and the tier's verdict
  ends `(N step(s) ran nothing: …)`. A step may declare its own `idle` pattern (a regex source).
  `--require-work` fails the tier when every step marked `runner` idled — the honest answer for a CI
  job or a push gate. Measured cause: during.day's fast tier runs turbo `--affected` inside its
  commands, so on a clean tree every suite step exited 0 having run nothing, the runner said PASS,
  the Stop hook was satisfied, and `main` stayed red in two workerd suites for days.
  
  `geonosis sync --check` prints `SKIP — sync has nothing to generate here: …` where it used to say
  "nothing for this command to generate here", so the verify runner reads it as idle.
- Updated dependencies [d90986b]
- Updated dependencies [d90986b]
- Updated dependencies [d90986b]
- Updated dependencies [7ee2097]
- Updated dependencies [c01ea60]
- Updated dependencies [d90986b]
- Updated dependencies [c13ade8]
- Updated dependencies [c8c5d51]
- Updated dependencies [08c9653]
  - @geonosis/doctor@2.7.0
  - @geonosis/verify@2.7.0
  - @geonosis/testbed@2.7.0
  - @geonosis/ledger@2.7.0
  - @geonosis/lint-parity@2.7.0
  - @geonosis/oxlint-plugin-biological-architecture@2.7.0
  - @geonosis/observability@2.7.0
  - @geonosis/ratchet@2.7.0
  - @geonosis/release@2.7.0
  - @geonosis/review@2.7.0
  - @geonosis/verify-arch@2.7.0
  - @geonosis/visual-diff@2.7.0
  - @geonosis/walk@2.7.0

## 2.6.1

### Patch Changes

- Updated dependencies [e1db50f]
- Updated dependencies [db89b0b]
  - @geonosis/ratchet@2.6.1
  - @geonosis/release@2.6.1
  - @geonosis/doctor@2.6.1
  - @geonosis/ledger@2.6.1
  - @geonosis/lint-parity@2.6.1
  - @geonosis/verify@2.6.1
  - @geonosis/observability@2.6.1
  - @geonosis/oxlint-plugin-biological-architecture@2.6.1
  - @geonosis/review@2.6.1
  - @geonosis/testbed@2.6.1
  - @geonosis/verify-arch@2.6.1
  - @geonosis/visual-diff@2.6.1
  - @geonosis/walk@2.6.1

## 2.6.0

### Patch Changes

- 58565d7: `geonosis update`'s first install says `--no-frozen-lockfile` on pnpm. pnpm's `install` is frozen by default wherever `CI` is set, so the install whose whole job is to rewrite the lock the bump just repinned refused on GitHub with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` while passing on every laptop; the flag is in the printed command, so what a reader repeats by hand is what ran.
- 58565d7: `geonosis update` names the lifecycle script an install died in even when the manager coloured the
  line it echoed. pnpm dims that line — measured 2026-09-07 on 11.5.1, the echo arrives as
  `ESC[2m$ exit 1ESC[22m` — and `ECHOED_COMMAND` anchors on `^$`, so the lookup that asks the manifest
  which script declared the failing command matched nothing and the step said only that the install
  failed. That is #312's own failure mode, which the naming exists to stop: a root `prepare` refuses
  in a git worktree, and a correct install reads as a FAIL that says nothing about why. The manager's
  styling is stripped before either pattern is read; `update --prove` said `NOT PROVEN … the refusing
  prepare is named as the lifecycle script` on BOTH bun 1.4.1 and pnpm, and now says PROVEN on both.
- Updated dependencies [58565d7]
- Updated dependencies [b7d8aae]
- Updated dependencies [58565d7]
- Updated dependencies [58565d7]
- Updated dependencies [58565d7]
  - @geonosis/doctor@2.6.0
  - @geonosis/verify@2.6.0
  - @geonosis/ratchet@2.6.0
  - @geonosis/release@2.6.0
  - @geonosis/ledger@2.6.0
  - @geonosis/lint-parity@2.6.0
  - @geonosis/observability@2.6.0
  - @geonosis/oxlint-plugin-biological-architecture@2.6.0
  - @geonosis/review@2.6.0
  - @geonosis/testbed@2.6.0
  - @geonosis/verify-arch@2.6.0
  - @geonosis/visual-diff@2.6.0
  - @geonosis/walk@2.6.0

## 2.5.3

### Patch Changes

- @geonosis/doctor@2.5.3
  - @geonosis/ledger@2.5.3
  - @geonosis/lint-parity@2.5.3
  - @geonosis/observability@2.5.3
  - @geonosis/oxlint-plugin-biological-architecture@2.5.3
  - @geonosis/ratchet@2.5.3
  - @geonosis/release@2.5.3
  - @geonosis/review@2.5.3
  - @geonosis/testbed@2.5.3
  - @geonosis/verify@2.5.3
  - @geonosis/verify-arch@2.5.3
  - @geonosis/visual-diff@2.5.3
  - @geonosis/walk@2.5.3

## 2.5.2

### Patch Changes

- ca64972: `geonosis update`'s "BY HAND — the floors this bump crossed name these changes in their own
  changelogs" block printed a floor's changelog as several duplicated entries: `Updated dependencies
  […]` printed once per crossed version instead of once per package, and a changeset naming two
  packages printed once under each. Now one line per package, `Updated dependencies […]` collapsed to
  name every sha, and an entry body two packages' changelogs both name prints once, attributed to
  both (#410).
- @geonosis/doctor@2.5.2
  - @geonosis/ledger@2.5.2
  - @geonosis/lint-parity@2.5.2
  - @geonosis/observability@2.5.2
  - @geonosis/oxlint-plugin-biological-architecture@2.5.2
  - @geonosis/ratchet@2.5.2
  - @geonosis/release@2.5.2
  - @geonosis/review@2.5.2
  - @geonosis/testbed@2.5.2
  - @geonosis/verify@2.5.2
  - @geonosis/verify-arch@2.5.2
  - @geonosis/visual-diff@2.5.2
  - @geonosis/walk@2.5.2

## 2.5.1

### Patch Changes

- 7f24da6: Every bin shim's `newest(src)` walked every file under `src/`, so touching only a `*.test.ts` made
  the bin refuse "dist is older than src" though tsup never reads that file. It now skips
  `*.test.ts`, `*.test.tsx`, `__tests__/` and `__fixtures__/` in all 18 shims (#399).
- 7f24da6: `update --registry <dir>` now writes the root overrides a packed candidate's own graph needs
  (#387): each tarball's manifest pins its siblings at the exact unpublished version, and a `file:`
  package's own dependencies resolve against npm unless the ROOT overrides them — measured against a
  real install, `No matching version found for @geonosis/doctor@2.5.0`. The ritual now writes
  `overrides` (bun) or `pnpm-workspace.yaml`'s `overrides:` (pnpm — `pnpm.overrides` in package.json
  is not read by pnpm 11, measured) for every tarball the directory holds, before the install, and
  records them in `bump-report.json` under `candidateOverrides`; a later `update --to <v>` without
  `--registry` removes exactly those, leaving a consumer's own untouched. `@geonosis/release`'s smoke
  run keeps its own copy of the same writer (`tooling/candidate-override-copies.test.ts` holds them
  together).
- 7f24da6: `geonosis update`'s "BY HAND — the floors this bump crossed name these changes in their own
  changelogs" block never printed empty: a floor that moved and whose own changelog named no entry
  for the target version — a heading with nothing under it, a version the reader could not find —
  now prints `moved, changelog entry for <v> not readable` instead of staying silent (#401).
- 7f24da6: `geonosis sync --check` names an `AGENTS.md` an older `geonosis sync` wrote instead of passing over
  it (#379): without a `.cursor/` directory `generate()` has nothing to compare, so the check exited 0
  over a file carrying the old generator's own header — that file is an orphan, not "nothing to
  generate here". `--check` now exits 1 and names the two doors: delete it, or regenerate it under the
  ledger's `AGENTS_MD_DOOR`. An `AGENTS.md` without that header (hand-written, or the ledger's own) is
  left alone.
- 7f24da6: `geonosis --version` (and `-v`) now print the door's own version, read off its `package.json`, and
  exit 0 (#388). Measured at 2.4.3 and 2.5.0: both flags fell through to the unknown-flag refusal and
  printed "geonosis: --version is not a flag of this command" followed by the whole help footer — the
  first thing a consumer types, answered with a fragment of `--help` instead of a version.
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
- Updated dependencies [7f24da6]
  - @geonosis/release@2.5.1
  - @geonosis/doctor@2.5.1
  - @geonosis/verify@2.5.1
  - @geonosis/ratchet@2.5.1
  - @geonosis/ledger@2.5.1
  - @geonosis/lint-parity@2.5.1
  - @geonosis/observability@2.5.1
  - @geonosis/oxlint-plugin-biological-architecture@2.5.1
  - @geonosis/review@2.5.1
  - @geonosis/testbed@2.5.1
  - @geonosis/verify-arch@2.5.1
  - @geonosis/visual-diff@2.5.1
  - @geonosis/walk@2.5.1

## 2.5.0

### Minor Changes

- 3e0681d: `geonosis update --dry-run --floors latest` now names every floor repin it would write, with the
  crossed-changelog reading off the registry, and says its report was not written (#374).
  
  `geonosis update --registry <dir>` runs the ritual over a packed candidate — a directory of
  tarballs resolves like a registry, repinning as `file:<tarball path>` and reading BY HAND off each
  one's own `CHANGELOG.md`; `--also-npm` lets a package the directory lacks fall back to the
  registry, refused otherwise (#330).
  **Known in 2.5.0:** the repin and the dry run are right; the real install of a candidate whose
  members depend on each other at an unpublished exact version still fails, because the ritual does
  not yet write the root overrides that make a `file:` group resolve (#387, measured by the first
  consumer to try it). The scratch shape that works is in that row; 2.5.x writes it for you.

### Patch Changes

- bbbdf06: `geonosis update` fixes credited to during.day's real 2.4.3 bump (#375, #376, #377, #378, #380):
  
  - a moved floor's "from" is the spec at HEAD, never the working tree's own rewrite of it, so a
    second run over manifests a first run already touched no longer prints `X → X`;
  - a floor `--floors latest`/`--floor` finds already at its target is unchanged, not moved — printed
    once per name, excluded from the moved count and from the commit body;
  - a floor's changelog is read once per package, never once per manifest that declares it;
  - the "lockfile moved but wasn't repinned" trigger excludes a fixed-group member (like
    `@geonosis/doctor`) that followed the group to this bump's own target, and the build step now runs
    a declared `verify.tiers.build` tier or skips naming why — never the repo's root build script,
    which may need deploy environment the bump cannot know;
  - under `--registry <dir>`, a declared floor the directory holds resolves off the candidate too,
    repinned as `file:<tarball path>` and read BY HAND off the tarball, refused by name unless
    `--also-npm` — exactly the fixed group's own rule.
- Updated dependencies [6b095e8]
  - @geonosis/release@2.5.0
  - @geonosis/doctor@2.5.0
  - @geonosis/ledger@2.5.0
  - @geonosis/lint-parity@2.5.0
  - @geonosis/observability@2.5.0
  - @geonosis/oxlint-plugin-biological-architecture@2.5.0
  - @geonosis/ratchet@2.5.0
  - @geonosis/review@2.5.0
  - @geonosis/testbed@2.5.0
  - @geonosis/verify@2.5.0
  - @geonosis/verify-arch@2.5.0
  - @geonosis/visual-diff@2.5.0
  - @geonosis/walk@2.5.0

## 2.4.3

### Patch Changes

- Updated dependencies [e4da607]
  - @geonosis/doctor@2.4.3
  - @geonosis/ledger@2.4.3
  - @geonosis/lint-parity@2.4.3
  - @geonosis/observability@2.4.3
  - @geonosis/oxlint-plugin-biological-architecture@2.4.3
  - @geonosis/ratchet@2.4.3
  - @geonosis/release@2.4.3
  - @geonosis/review@2.4.3
  - @geonosis/testbed@2.4.3
  - @geonosis/verify@2.4.3
  - @geonosis/verify-arch@2.4.3
  - @geonosis/visual-diff@2.4.3
  - @geonosis/walk@2.4.3

## 2.4.2

### Patch Changes

- Updated dependencies [f3c3487]
  - @geonosis/doctor@2.4.2
  - @geonosis/ledger@2.4.2
  - @geonosis/lint-parity@2.4.2
  - @geonosis/observability@2.4.2
  - @geonosis/oxlint-plugin-biological-architecture@2.4.2
  - @geonosis/ratchet@2.4.2
  - @geonosis/release@2.4.2
  - @geonosis/review@2.4.2
  - @geonosis/testbed@2.4.2
  - @geonosis/verify@2.4.2
  - @geonosis/verify-arch@2.4.2
  - @geonosis/visual-diff@2.4.2
  - @geonosis/walk@2.4.2

## 2.4.1

### Patch Changes

- Updated dependencies [cb783e8]
  - @geonosis/doctor@2.4.1
  - @geonosis/ledger@2.4.1
  - @geonosis/lint-parity@2.4.1
  - @geonosis/observability@2.4.1
  - @geonosis/oxlint-plugin-biological-architecture@2.4.1
  - @geonosis/ratchet@2.4.1
  - @geonosis/release@2.4.1
  - @geonosis/review@2.4.1
  - @geonosis/testbed@2.4.1
  - @geonosis/verify@2.4.1
  - @geonosis/verify-arch@2.4.1
  - @geonosis/visual-diff@2.4.1
  - @geonosis/walk@2.4.1

## 2.4.0

### Minor Changes

- 4962ed6: Every publishable package names `CHANGELOG.md` in `files`, not only the five floors. Measured on the 2.4.0 tarballs before they shipped: **0 of the 22 group packages carried one**, so `geonosis update`'s `BY HAND` block printed nothing for a group bump — the third consecutive release, in the cut where a consumer would have read the sweep, the holder and the Stop-hook fixes. `tooling/floor-changelog-shipped.test.ts` now holds the whole workspace rather than the floors, so a package cannot fall out of the convention silently.
  
  The doctor's `exams` check asks one question per EXAM instead of one per package. `@geonosis/db` ships three (`sessionConformance`, `entityConformance`, `singletonConformance`), and importing any one of them anywhere used to answer OK for the whole package — so a consumer running the session exam alone read green while two floors' behaviour was never exercised. That is this check's own docstring failing inside the check written to state it.
  
  The plugin-drift line knows a release candidate. A tree whose `overrides`/`resolutions` point a kit package at a `file:`, `link:`, `portal:` or `.tgz` spec is installed from a candidate the registry has never seen, so `claude plugin update` cannot reach that version at all — the WARN was unavoidable and unactionable for the whole life of every RC, in the window a consumer reads the doctor hardest. It now says the packages are a candidate and that the question becomes real when that version publishes.
  
  `smoke run` refuses a STALE recording instead of rendering a verdict over it. The 2.4.0 sweep headlined `FAIL … the release broke 1 of their gates` and printed `STALE` as its last line, fifteen lines below: both true, and the FAIL was a consumer frozen two releases back crossing a break declared in the one before, while the tree they actually have had migrated past it and was green. A stale recording cannot answer whether THIS release breaks them — only what it does to a tree nobody has — so it leads the block, names the command that re-takes it, and exits 2, the code for a run that could not be made.

### Patch Changes

- bef73fb: Every shim tells a tree that was never built from a build that fell behind. `newest(dist)` answers 0 for a directory that is not there and for one that is merely old, so both conditions were one comparison and one sentence — and the staleness sentence was printed over trees that had never been built at all. It blocked a session's turn in a fresh git worktree, which has no `dist` because `dist` is not committed, with a message about a build going stale. Only one of the two is evidence of a mistake, and the two send a reader to different places.
  
  The test that holds it plants BOTH cases and requires different sentences, which the previous one never did: it planted only a stale `dist`, so the check had never been shown a case whose answer should differ. Named for what it is, since the same gap produced two wrong published numbers the same day — a probe never shown a differing case has not been shown to discriminate, which is this repo's own "a gate never seen red has not been shown to measure", one layer down, applied to the thing doing the observing.
  
  (This changeset names four packages of the fixed group deliberately: the group versions as one number and a changeset's description lands only in the packages it names, so naming several puts it in more than one place a reader might look. See #356.)
- Updated dependencies [4962ed6]
- Updated dependencies [bef73fb]
- Updated dependencies [3b7b2ae]
- Updated dependencies [a5b2319]
- Updated dependencies [56e0f33]
  - @geonosis/doctor@2.4.0
  - @geonosis/release@2.4.0
  - @geonosis/verify@2.4.0
  - @geonosis/ratchet@2.4.0
  - @geonosis/ledger@2.4.0
  - @geonosis/lint-parity@2.4.0
  - @geonosis/observability@2.4.0
  - @geonosis/oxlint-plugin-biological-architecture@2.4.0
  - @geonosis/review@2.4.0
  - @geonosis/testbed@2.4.0
  - @geonosis/verify-arch@2.4.0
  - @geonosis/visual-diff@2.4.0
  - @geonosis/walk@2.4.0

## 2.3.1

### Patch Changes

- Updated dependencies [88d2e4a]
- Updated dependencies [0f6f7ef]
- Updated dependencies [204d24c]
- Updated dependencies [9e2bc64]
  - @geonosis/verify@2.3.1
  - @geonosis/oxlint-plugin-biological-architecture@2.3.1
  - @geonosis/doctor@2.3.1
  - @geonosis/ledger@2.3.1
  - @geonosis/lint-parity@2.3.1
  - @geonosis/observability@2.3.1
  - @geonosis/ratchet@2.3.1
  - @geonosis/release@2.3.1
  - @geonosis/review@2.3.1
  - @geonosis/testbed@2.3.1
  - @geonosis/verify-arch@2.3.1
  - @geonosis/visual-diff@2.3.1
  - @geonosis/walk@2.3.1

## 2.3.0

### Minor Changes

- 3dac9a7: **Three things `update` got wrong on a real bump (#311, #312, #313).**
  
  - The frozen install runs `--ignore-scripts` by DEFAULT and says so in the command it prints: the
    first install already ran every lifecycle script, and a root `prepare` that installs git hooks
    refuses a git worktree — which is exactly where a bump happens. A failed install now names the
    lifecycle script it died in, read from each manager's own output (measured on bun 1.4.0 and
    pnpm 11.5.1, which print three different shapes between them).
  - A frozen install refused by a lockfile a moved floor left stale gets the SURGICAL recipe by name:
    which entries to rewrite in place, and why deleting them is not the answer — one measured bump
    that deleted three stale lines re-resolved Next, oxlint, better-auth and opennext with them.
  - `from` is read off the committed manifest when this command has already rewritten the working
    one, so a bump split across two runs keeps its `BY HAND` block instead of reading an empty range.
- 3dac9a7: **The law a repo never declared is still read (#315).** `retiredNamesInLaw` read only
  `geonosis.json → law.file`, which most consumers never write, so the block that exists to catch a
  law left lying after a bump read nothing at all: a `CLAUDE.md` still naming a retired package went
  unprinted on every tree that had not declared one. With no `law.file`, `CLAUDE.md` and `AGENTS.md`
  are read by default — and everything they `@import`, each file once. A declared `law.file` still
  wins.
- 3dac9a7: **A bump whose lockfile moved more than it repinned runs the build (#109).** `geonosis update`
  reads the lockfile either side of the install, subtracts the packages it repinned, and runs the
  `build` tier — or the root `build` script — before anyone is told PASS, naming the extra packages
  either way. A tree that declares neither is told so rather than gated. The workspace-state fact
  (`node_modules/.pnpm-workspace-state-v1.json` decides relinking, which is why `--force` and
  deleting `.modules.yaml` change nothing) is in the command's own usage.
- 3dac9a7: **A `dx` counter family, fed from the kit's own reports (#93).** `bumpDurationMs` and
  `timeToGreenDoctorMs` read `.geonosis/bump-report.json` — which now records how long the bump took
  and how long each step that RAN took; `openBacklogRows` counts the rows of a register nobody has
  closed, `path` required and `done` the repo's own word. A bump whose doctor was red has no
  time-to-green, and all three refuse rather than reading a zero.
- 3dac9a7: **`geonosis explain <rule|counter|tier|package>` (#91).** The effective value of everything a name
  decides, beside the file that decided it: a rule's severity and options out of `.oxlintrc.json` with
  the presets that carry it, a counter's entry and its baseline, a tier's steps, and a package's own
  `--print-config-shape` beside the config files this repo actually has. The doctor's "it runs on its
  defaults, whatever they are" now names that command instead.
- 3dac9a7: **The seam figure is measured from where the branch left the default one (#314).** Diffed against
  HEAD it measured the BUMP, not the adoption: on a branch whose deletion is already committed —
  which is every branch by the time anyone runs the bump — `git diff HEAD` sees a clean tree and the
  row read `0 deleted, 0 added` over a seam that had lost two hundred lines. `seamMovement` now
  defaults to the default branch this one left, takes a ref the caller names over it, and the report
  line says which two refs it diffed.
- 3dac9a7: **A typecheck step that has been watched failing (#296).** The first step of every fast tier — the
  kit's own and every scaffolded repo's — declared no plant, so it read `PASS (unproven)` for ever and
  nobody asked which step for a week. A scaffolded tier now plants a type error into a workspace
  `src/` and requires `TS2322`: unlike a lint rule it needs no preset, no option and no engine, so it
  holds on any repo.
  
  The scaffolded ratchet also gains one `testFailures` counter per workspace, running that
  workspace's own test script and reading the report that script writes — the reports the scaffold
  was already writing and nothing was reading.

### Patch Changes

- 3dac9a7: `rulesFor` writes an answer for any rule the presets bring, not only for one that would refuse without it — an inert default is still a default the scaffold owns (D-031). The scaffold hands `no-runtime-dead-affordance` the same element→atom map it gives `no-raw-html-atoms`; the doctor over a scaffolded tree stops answering UNJUDGED for a control no probe could render.
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [3dac9a7]
- Updated dependencies [a8ab653]
  - @geonosis/oxlint-plugin-biological-architecture@2.3.0
  - @geonosis/doctor@2.3.0
  - @geonosis/release@2.3.0
  - @geonosis/verify-arch@2.3.0
  - @geonosis/ratchet@2.3.0
  - @geonosis/walk@2.3.0
  - @geonosis/lint-parity@2.3.0
  - @geonosis/verify@2.3.0
  - @geonosis/visual-diff@2.3.0
  - @geonosis/ledger@2.3.0
  - @geonosis/review@2.3.0
  - @geonosis/testbed@2.3.0
  - @geonosis/observability@2.3.0

## 2.2.0

### Minor Changes

- d15a654: **A floor adoption is measured (#280).** The user's rule — a floor is adopted the day it deletes
  more than it adds — had no instrument: during.day's four db floors came out +222/−225 and its
  workflows floor +1807/−1493, and both numbers were read by nobody until they were asked for. A
  consumer declares `adoption.seams: [globs]` in `geonosis.json` (default none, and a repo that
  declares none gets no figure rather than a figure about everything). `geonosis update` then reports
  lines deleted against lines added over those globs, `git diff --numstat` between the commit the bump
  started from and the working tree, in the verdict and in the bump report. `geonosis-ratchet` gains
  `adoptionSeamLines`, the lines those globs still hold — a number the ratchet already refuses to let
  grow. A snapshot records the same figure for its consumer and `geonosis-release adoption` carries it
  per consumer (MEASURED: a consumer's `.geonosis/` is an excluded directory, so their own bump report
  never reaches a recording — the figure is taken where the tree is read).
- d15a654: **A bump names what the floors it crossed changed, and runs the tier it left behind (#268).** The
  `BY HAND` block was driven by the doctor's required-option FAILs alone, so `--floors latest` across
  a floor minor that changed `sessionDb`'s key printed nothing and the consumer's own tests found it.
  `update` now reads each bumped floor's own `CHANGELOG.md` out of what the install unpacked, for the
  versions crossed, and prints every change its author named — and says so by name when a floor ships
  no changelog to read (measured: `npm pack --dry-run --json` over a floor carries `dist`,
  `package.json`, `README.md` and `LICENSE`; CHANGELOG is not on npm's always-included list, so the
  floors name it in `files` now). A seventh ritual step runs the tier this tree calls `fast` in
  `geonosis.json` after the frozen install: a bump cannot report PASS over a tree it has just
  reddened, and a repo that declares no tier is told so rather than passed over.
- d15a654: **A bump names the law lines that still name a retired package (#279).** `update` and `sync` repin
  manifests and regenerate AGENTS.md and leave a consumer's LAW saying `sagaflow-js` after the bump
  onto the engine that replaced it — the law lies until a human edits it, and nothing said the lines
  were there. `update` now reads the law (`geonosis.json → law.file`) and every skill it imports, and
  prints each line naming a package the kit replaced as `BY HAND`, with the file, the line number and
  what replaced it. The replacement map is the kit's own history, shipped with it.

### Patch Changes

- d15a654: **The purge is per checkout, and the bump says so (#242).** A bump run in a worktree and merged into
  another checkout leaves that checkout's nested `node_modules/@geonosis/*` untouched — the manifests
  and the lockfile travel with a merge and a directory outside the workspace globs does not; during.day
  reported one the doctor's split-group FAIL caught on the receiving tree. The commit body now says to run
  `geonosis update --to <the same version>` in every checkout that receives the merge, and `--prove`
  plants a nested copy in a SECOND checkout of the same bump — proving both that it survives the merge
  and that the same `--to` removes it idempotently.
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [45f3d79]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
- Updated dependencies [c4c9330]
- Updated dependencies [d15a654]
- Updated dependencies [d15a654]
  - @geonosis/ratchet@2.2.0
  - @geonosis/release@2.2.0
  - @geonosis/oxlint-plugin-biological-architecture@2.2.0
  - @geonosis/doctor@2.2.0
  - @geonosis/verify@2.2.0
  - @geonosis/ledger@2.2.0
  - @geonosis/lint-parity@2.2.0
  - @geonosis/testbed@2.2.0
  - @geonosis/observability@2.2.0
  - @geonosis/review@2.2.0
  - @geonosis/verify-arch@2.2.0
  - @geonosis/visual-diff@2.2.0
  - @geonosis/walk@2.2.0

## 2.1.0

### Minor Changes

- c1f894d: **The bump report says what every step did, and a FAIL claims nothing (#232, #233, #240).** `.geonosis/bump-report.json` carried one `steps` entry — `install` — so a consumer's failed bump said what broke and nothing about resolve, repin, purge, the frozen install or the doctor. It now carries all six in ritual order, each with `ran` and `ok`, the ones the run never reached marked as such. The printed commit body is derived from those verdicts and is not printed at all for a bump whose `ok` is false: the text a consumer is told to paste read "bun install and bun install --frozen-lockfile clean; geonosis-doctor --only loaded not run" three lines under `FAIL bun install`. And `from` is now `{ version, manifests[] }`, so a group found at two versions names the manifest that held each.
- 511b449: **The install step is the consumer's tree, and a FAIL says what it left (#231).** `geonosis update` runs both installs with lifecycle scripts on, so a `prepare` that refuses — lefthook against a worktree's shared `core.hooksPath` — fails step 4 with every manifest already rewritten, and the verdict said only which command exited non-zero. It now takes `--install-args "<args>"`, handed word for word to BOTH installs, and a failed install prints the version the manifests stay repinned at, that nothing was rolled back, and the command to finish by hand. `update --prove` plants a refusing `prepare` on each package manager it finds and proves both halves there.
- c54d6a9: **The bump moves the floors, and names what no command can do (#221, #225).** `geonosis update --to` repinned the fixed group and left every floor package where it was, with one line saying so. It now takes `--floors latest` and `--floor <package>@<version>` (repeatable): each floor is resolved against the registry with everything else BEFORE a byte is written (#148), a `--floor` naming a package no manifest here declares is refused rather than skipped, and the ones that move become `moved <at> <name> <from> → <to>` in the report and in the printed commit body.
  
  **And the doctor answers to the name it carries.** `required-options.ts` emits `check: 'loaded'` and was run by the `exercised` pass, so `geonosis-doctor --only loaded` — what the bump runs — could never print it: measured 2026-09-02 on a planted tree, `--only loaded` said nothing about a rule enabled without its option and `--only exercised` printed it under a heading called "loaded". That is how 2.0.0's new refusals reached a consumer's config with nothing between them and it. The check now runs under `loaded`, and the bump report carries a `BY HAND` block naming every rule and the option it needs. `update --prove` grows both plants and passes on bun and pnpm alike.

### Patch Changes

- 849f72e: **A scaffolded tree earns no WARN of its own (#215).** `create-geonosis` and `geonosis init` left six out of the box, and a scaffold whose own doctor is dirty teaches every repo it makes that a WARN is scenery. The root now declares a `prove` script and the `full` tier names it when the root has one, so the counters are proved rather than only compared; `sync:graph` names the ledger bin the scaffold already runs, from the same one list `finish` runs it from; and `--kit` declares at the root exactly what a registry install would, instead of every package it linked so the bins resolve. Two of the six were the doctor contradicting itself: a `jsPlugins` entry is a caller with no bin to call — pnpm 11.8.0 resolves only DIRECT dependencies from a directory, so dropping that declaration is how a root config stops linting — and a `geonosis.json` block whose reader the declared door brings is read by something, which is the shape #177 asks a root to have.
- f252d95: **A harness says when the install edited the tree it was measuring (#216).** Measured on pnpm 11.5.1 and 11.8.0 against a `min-release-age=7` in `~/.npmrc`: installing a package younger than that APPENDS a `minimumReleaseAgeExclude:` block to the tree's `pnpm-workspace.yaml`, and pinning the manager version does not stop it — 11.5.1 rewrites it exactly as 11.8.0 does. The smoke now compares `.npmrc`, `bunfig.toml` and `pnpm-workspace.yaml` across its `run/` install and carries a finding naming the file, so a run over a tree that is no longer byte-for-byte the consumer's says so instead of reporting on it silently. `update --prove` writes `packageManager` into the scratch manifest — the manager and version that ran, so a rerun of that directory gets the same one — and carries one proof per manager that every config file the fixture wrote came back byte-identical.
- Updated dependencies [e0da9a3]
- Updated dependencies [a200ec5]
- Updated dependencies [ef19211]
- Updated dependencies [c94d02e]
- Updated dependencies [e04c395]
- Updated dependencies [e932127]
- Updated dependencies [849f72e]
- Updated dependencies [6cdb38c]
- Updated dependencies [f252d95]
- Updated dependencies [c54d6a9]
- Updated dependencies [e419bb4]
- Updated dependencies [a016fa4]
- Updated dependencies [4c91653]
- Updated dependencies [c3223cc]
- Updated dependencies [b7dab40]
- Updated dependencies [40710b3]
  - @geonosis/doctor@2.1.0
  - @geonosis/ledger@2.1.0
  - @geonosis/observability@2.1.0
  - @geonosis/testbed@2.1.0
  - @geonosis/walk@2.1.0
  - @geonosis/release@2.1.0
  - @geonosis/oxlint-plugin-biological-architecture@2.1.0
  - @geonosis/lint-parity@2.1.0
  - @geonosis/ratchet@2.1.0
  - @geonosis/review@2.1.0
  - @geonosis/verify@2.1.0
  - @geonosis/verify-arch@2.1.0
  - @geonosis/visual-diff@2.1.0

## 2.0.0

### Major Changes

- 6d14aa2: The D-051 train. Three breaking changes ride it: `time-through-the-door` REQUIRES `door` (its
  hardcoded consumer path is gone); the `backend-sagaflow-cf` preset is `backend-workflows-cf` (the
  old name is an alias for this release only); `@geonosis/events` leaves the fixed version group onto
  its own line. Every method package moves together to 2.0.0.

### Minor Changes

- bcf0788: **`geonosis sync --help` wrote ten generated files (backlog #175).** The door answers `--help` for a
  registry command that declares a `usage` and hands the flag on otherwise, and `sync`, `discover` and
  `skills` declared none — so the flag reached `run()` as an argument the command ignored and the run
  went ahead. All three now carry a usage line, pinned by a test over the registry, and an unrecognised
  flag is refused by name with exit 2 before anything is written. `--target` is no longer a copy of the
  ledger's target list either: the copy was three names long and refused the two doc targets the
  command's own refusal points at.
- 38889b1: **`geonosis init` leaves a plant its own lint can be watched failing on (#65).** A preset that brings `step-declares-compensation-or-none` puts a `proves` on the lint step of `geonosis.json`: it writes `createStep(name, invoke)` — no third argument, no `noCompensation`, the shape a reviewer cannot tell apart from a forgotten undo — and requires the step to go red naming the rule. Presets with no rule to catch a plant leave the tier the plain commands it was.
- 35502e0: **`geonosis sync` no longer writes `AGENTS.md` (D-054 as amended, backlog #169).** The file had two
  generators of different shapes — the ledger's projection (the law's rules section, one line per
  skill, one row per scoped rule) and this command's byte copy of the whole law behind a banner — so a
  repo running both kept whichever ran last. The projection is the one that survives: `geonosis sync
  --target agents-md --write AGENTS.md`, which this command passes through to `geonosis-ledger`, exit
  code and all. `--targets agents` is refused by name and points there. The Cursor rules are
  unchanged, and the over-ceiling copy refusal (`law.maxLines`, `law.copy`) now guards the copy that
  is left, `.cursor/rules/law.mdc`.
- e9a41a7: **One scaffold source, two doors (#198).** `geonosis init` and `create-geonosis` each built the
  `verify` tiers from their own literals, so a repo's gates depended on which command had made it: one
  door planted the lint proof and skipped the formatter, the other did the reverse. Both now write
  from `tiersFor` in `@geonosis/cli`, and `build` / `format:check` are named only when the root
  declares that script — `pnpm build` in a `create-geonosis` tree exits 1 with "Command build not
  found". `tooling/one-scaffold-source.test.ts` runs both doors over one tree and reads the tiers back
  through verify's own reader.
- 539a96c: **`geonosis update --to <version>` — the bump ritual as one command, and the report as the evidence.** Every `@geonosis/*` pin in every workspace is resolved against the registry BEFORE a byte is written, so one missing version refuses the whole bump and leaves the tree untouched (#148: bun writes the manifest entry before resolving, and a failed `bun add pkg@v` leaves a manifest naming a version that does not exist). Then: rewrite the fan-out, purge the nested copies, install with the manager the lockfile names, install again frozen, and ask `geonosis-doctor --only loaded` whether declared is what resolution finds — `.geonosis/bump-report.json` plus a printed commit body. `--prove` runs the whole ritual over a scratch consumer it builds, with a nested stale copy planted for the purge and a missing version planted for the resolve, on every package manager it can find; each claim names its manager and a missing manager is printed UNPROVEN. The purge takes the WHOLE `node_modules` of a non-root workspace, never the root's: measured on pnpm 11.8.0, removing only `node_modules/@geonosis` is repaired by no install at all — plain, `--force` and after deleting `.modules.yaml` all print "Already up to date" and exit 0 over a tree the package is missing from (#154).
- 533f24d: **Every reader of the law asks `geonosis.json → law.file` (D-054).** `CLAUDE.md` may be one line
  importing the law's real source, so a tool that opened it by name introduced a repo's law as one
  line long: `geonosis sync` projected the importer into `.cursor/rules/law.mdc` while its own
  over-ceiling refusal measured the declared file, and the MCP preamble stated the importer's length.
  `lawFileOf` is the one resolver both now read, defaulting to `CLAUDE.md` for a repo that declares
  nothing.

### Patch Changes

- 3258f5f: **`geonosis-release published --group` — the release is the group resolving from npm, not the publish exiting zero (#147).** Every `package.json` in the tree against the version the registry answers, no sampling, `considered` naming its own denominator and the manifests it excused. `--wait <seconds>` polls through the few minutes in which a freshly published name still 404s. Exit 0 the whole group, 1 a gap named per package, 2 the registry could not be asked — which is not "not published". The registry is read over HTTP and never through `npm view` or `bun pm view`: the manager's manifest cache is what read one release behind and aborted a consumer's bump.
- ccfc3c3: **`geonosis sync`'s hints spell the AGENTS.md door the one way it takes (#207).** Three sentences named the same command and one of them wrote `--write AGENTS.md`, which this door does not accept — a consumer ran the line it was handed and got a usage refusal. The invocation is one exported string now, and a test holds every sentence that names the door against it.
- Updated dependencies [d22ae0f]
- Updated dependencies [c3c40e1]
- Updated dependencies [8ff5e21]
- Updated dependencies [75eed83]
- Updated dependencies [a5e2341]
- Updated dependencies [64e4e41]
- Updated dependencies [36eafc4]
- Updated dependencies [a0f456c]
- Updated dependencies [20b6b97]
- Updated dependencies [6c88bf1]
- Updated dependencies [6b5b3db]
- Updated dependencies [c6761f6]
- Updated dependencies [07cc9f2]
- Updated dependencies [24e4ba4]
- Updated dependencies [2ed0d01]
- Updated dependencies [364cabd]
- Updated dependencies [c68644c]
- Updated dependencies [5de0fba]
- Updated dependencies [5d9aadb]
- Updated dependencies [4b61257]
- Updated dependencies [c43551a]
- Updated dependencies [0a35d2a]
- Updated dependencies [8349abc]
- Updated dependencies [abd2f2d]
- Updated dependencies [38889b1]
- Updated dependencies [3258f5f]
- Updated dependencies [e0aa82f]
- Updated dependencies [adebb0c]
- Updated dependencies [d83f48a]
- Updated dependencies [93e5b85]
- Updated dependencies [6883b18]
- Updated dependencies [3e586a5]
- Updated dependencies [7de7bf6]
- Updated dependencies [7de7bf6]
- Updated dependencies [2fb94d5]
- Updated dependencies [7533b00]
- Updated dependencies [5c25a6d]
- Updated dependencies [1499635]
- Updated dependencies [15663aa]
- Updated dependencies [7de7bf6]
- Updated dependencies [415c466]
- Updated dependencies [b979c78]
- Updated dependencies [c1ee50d]
- Updated dependencies [74ae3ec]
- Updated dependencies [97bc8e9]
  - @geonosis/oxlint-plugin-biological-architecture@2.0.0
  - @geonosis/doctor@2.0.0
  - @geonosis/ledger@2.0.0
  - @geonosis/verify@2.0.0
  - @geonosis/testbed@2.0.0
  - @geonosis/verify-arch@2.0.0
  - @geonosis/walk@2.0.0
  - @geonosis/release@2.0.0
  - @geonosis/ratchet@2.0.0
  - @geonosis/lint-parity@2.0.0
  - @geonosis/observability@2.0.0
  - @geonosis/review@2.0.0
  - @geonosis/visual-diff@2.0.0

## 1.4.0

### Patch Changes

- Updated dependencies [a7fe848]
- Updated dependencies [ce2167f]
- Updated dependencies [0d99139]
- Updated dependencies [7c10970]
- Updated dependencies [8f5dc0c]
- Updated dependencies [d5ee3d1]
- Updated dependencies [bc2926f]
- Updated dependencies [5df33fd]
- Updated dependencies [d23aef3]
- Updated dependencies [a430c81]
- Updated dependencies [565db59]
- Updated dependencies [ce2167f]
- Updated dependencies [113fdb2]
- Updated dependencies [3de7f28]
- Updated dependencies [c712f3d]
- Updated dependencies [0b55a82]
- Updated dependencies [38524fb]
- Updated dependencies [d6d5e2f]
- Updated dependencies [143281d]
- Updated dependencies [1a2f36c]
- Updated dependencies [ef29fc0]
  - @geonosis/verify@1.4.0
  - @geonosis/ratchet@1.4.0
  - @geonosis/doctor@1.4.0
  - @geonosis/oxlint-plugin-biological-architecture@1.4.0
  - @geonosis/release@1.4.0
  - @geonosis/lint-parity@1.4.0
  - @geonosis/ledger@1.4.0
  - @geonosis/observability@1.4.0
  - @geonosis/review@1.4.0
  - @geonosis/testbed@1.4.0
  - @geonosis/verify-arch@1.4.0
  - @geonosis/visual-diff@1.4.0
  - @geonosis/walk@1.4.0

## 1.3.0

### Patch Changes

- 0a7673c: **`geonosis --print-config-shape` (#75).** The door says it holds no configuration of its own, names
  what `init` writes and what `discover` reads, and points at the per-command form — a flag after the
  command belongs to the command, `--print-config-shape` included.
  
  **`sync --targets agents,cursor` — each target opt-in (#77).** `--write` wrote AGENTS.md and nine
  `.cursor/rules/*.mdc` into a repo that does not use Cursor: nine generated files nobody asked for,
  nobody reads and nothing gates. `--targets` names which tools the law is projected onto, an unknown
  one is refused with the list, and `--check` polices only the targets in play. With none named it
  writes the ones the repo ALREADY generates — `agents` always, `cursor` where a `.cursor/` directory
  says so — so nothing changes for anyone who was using Cursor.
  
  **`sync` writes the gate into every file, and prints the line to add (#82).** Each generated file carries `geonosis:gated-by: geonosis sync --check` — the marker `geonosis-doctor --only drift` looks for — and `--write` prints the exact script to add when nothing in the repo runs it, and says so when something already does.
  
  **`init` names the gate that reads each file it wrote (#83).** `wrote geonosis.ratchet.json — read back by `geonosis-ratchet``, beside the path, at the moment it writes — and nothing for a file it kept. The family is sync's ungated law copy and init's own second baseline; the checklist is in `docs/releasing.md`.
- Updated dependencies [915ac7c]
- Updated dependencies [c340de0]
- Updated dependencies [c9b63c0]
- Updated dependencies [db1cebd]
- Updated dependencies [12a942f]
- Updated dependencies [79a2880]
- Updated dependencies [b9ad142]
- Updated dependencies [c8316d4]
- Updated dependencies [2d1d841]
- Updated dependencies [0a7673c]
- Updated dependencies [c8316d4]
- Updated dependencies [0a7673c]
- Updated dependencies [0c04909]
- Updated dependencies [2d1d841]
- Updated dependencies [f37950f]
- Updated dependencies [0a7673c]
- Updated dependencies [2d1d841]
- Updated dependencies [2d1d841]
- Updated dependencies [228566f]
- Updated dependencies [36759c8]
- Updated dependencies [2151c37]
- Updated dependencies [fe413db]
- Updated dependencies [2d1d841]
- Updated dependencies [0a7673c]
- Updated dependencies [0a7673c]
- Updated dependencies [2d1d841]
  - @geonosis/doctor@1.3.0
  - @geonosis/oxlint-plugin-biological-architecture@1.3.0
  - @geonosis/ratchet@1.3.0
  - @geonosis/testbed@1.3.0
  - @geonosis/observability@1.3.0
  - @geonosis/ledger@1.3.0
  - @geonosis/lint-parity@1.3.0
  - @geonosis/release@1.3.0
  - @geonosis/review@1.3.0
  - @geonosis/verify@1.3.0
  - @geonosis/verify-arch@1.3.0
  - @geonosis/visual-diff@1.3.0
  - @geonosis/walk@1.3.0

## 1.2.0

### Patch Changes

- Updated dependencies [90eddee]
- Updated dependencies [0268ee7]
- Updated dependencies [eb94097]
  - @geonosis/doctor@1.2.0
  - @geonosis/release@1.2.0
  - @geonosis/ledger@1.2.0
  - @geonosis/lint-parity@1.2.0
  - @geonosis/observability@1.2.0
  - @geonosis/oxlint-plugin-biological-architecture@1.2.0
  - @geonosis/ratchet@1.2.0
  - @geonosis/review@1.2.0
  - @geonosis/testbed@1.2.0
  - @geonosis/verify@1.2.0
  - @geonosis/verify-arch@1.2.0
  - @geonosis/visual-diff@1.2.0
  - @geonosis/walk@1.2.0

## 1.1.0

### Minor Changes

- 7fca7b6: `geonosis release migrations|plan|prove|deployed` through the command registry, and therefore
  through MCP: the release gate answers at the same door as every other bin, with the child's exit
  code passed through verbatim.
- 749239a: `geonosis-release deployed --check` compares `.geonosis/deployed.json` — what a pipeline reported
  after promote — against the wrangler configs and secret names the tree declares. Drift either way
  is exit 1; the file being absent is exit 2, never a pass. `@geonosis/doctor` gains a seventh line,
  `deployed`, over the same file, reading it rather than importing the release package.

### Patch Changes

- Updated dependencies [9f8207b]
- Updated dependencies [8982fad]
- Updated dependencies [39ac31b]
- Updated dependencies [749239a]
- Updated dependencies [8464846]
- Updated dependencies [2ebded4]
  - @geonosis/release@1.1.0
  - @geonosis/doctor@1.1.0
  - @geonosis/oxlint-plugin-biological-architecture@1.1.0
  - @geonosis/ledger@1.1.0
  - @geonosis/lint-parity@1.1.0
  - @geonosis/observability@1.1.0
  - @geonosis/ratchet@1.1.0
  - @geonosis/review@1.1.0
  - @geonosis/testbed@1.1.0
  - @geonosis/verify@1.1.0
  - @geonosis/verify-arch@1.1.0
  - @geonosis/visual-diff@1.1.0
  - @geonosis/walk@1.1.0

## 1.0.1

### Patch Changes

- 1c2ee0b: **Every package ships its declarations and says where they are.** `@geonosis/visual-diff` and
  `@geonosis/verify` emitted no `.d.ts` at all (TS7016 in a consumer: the comparator every visual test
  calls became `any` at the one seam that decides whether a screenshot regressed), and no package
  declared `types` — the nineteen that worked did so through the sibling-file fallback, which ends the
  day `exports` gains a condition. Every export now carries a `types` condition beside `default`, every
  manifest a `types` field, and `tooling/types.test.ts` holds all twenty-one to it after the build.
  
  `geonosis-verify-arch` prints a check once when its label is its id ("direction, orphan", not
  "direction direction").
- 7dcae6a: **`geonosis init` writes the files that are absent and keeps the ones that exist.** It refused the
  whole run when ANY of its four files was there — so a repo that adopted the ratchet weeks ago could
  never get a `geonosis.json` from it, and "an existing repo" was exactly the repo it could not serve
  (during.day: three absent, one present, nothing written). Each absent file is written, each existing
  one is kept byte for byte and named `kept … (already yours)`; nothing is merged into anything — a
  merge that guessed is an overwrite with a nicer name. All four present → "nothing to write", exit 0.
  
  A flag init does not have (`--preset`, singular) is refused by name with the syntax; the no-preset
  refusal now shows `geonosis init --presets <a,b,c>` beside the vocabulary; and `init --help` prints
  that line at exit 0 — the door had promised "everything after the command is the command's own,
  `--help` included" and init did not honour it (#57).
  
  A kept `geonosis.ratchet.json` names its own baseline (`baseline: "scripts/gate-baseline.json"`);
  init resolves that path and keeps or writes THAT file — testing the root default wrote a second
  baseline nothing reads into a repo that already had one.
- Updated dependencies [1c2ee0b]
  - @geonosis/doctor@1.0.1
  - @geonosis/ledger@1.0.1
  - @geonosis/lint-parity@1.0.1
  - @geonosis/observability@1.0.1
  - @geonosis/oxlint-plugin-biological-architecture@1.0.1
  - @geonosis/ratchet@1.0.1
  - @geonosis/review@1.0.1
  - @geonosis/testbed@1.0.1
  - @geonosis/verify@1.0.1
  - @geonosis/verify-arch@1.0.1
  - @geonosis/visual-diff@1.0.1
  - @geonosis/walk@1.0.1

## 1.0.0

### Major Changes

- 88d7bf6: **`@geonosis/cli` — one declarative command registry, and the `geonosis` bin over it.** Fifteen
  commands: eleven that front a kit bin by SPAWNING it, and four that are the CLI's own. The registry
  is the list every door reads — the MCP server serves these commands, not a second copy of them.
  
  A wrapped command passes the child's exit code through unchanged. The nine bins agree that 0 is
  clean, 1 is a finding or a refusal and 2 is a run that could not be made at all, and a wrapper that
  normalised a 2 into a 1 would have invented a finding out of a tool that never ran. The bin is found
  by resolution — the repo's copy first, this package's second, and it prints which one it ran when it
  falls back, because unseen version skew is the failure `geonosis-doctor` exists to catch.
  
  - `init` writes the four config files an existing repo needs and refuses to overwrite any of them —
    and when one exists it writes none of the others. It will not enable a rule whose options only the
    repo can answer, because an enabled rule without its options refuses the whole run at load
    (D-031); which rules those are is MEASURED by constructing each rule with no options, never listed.
  - `sync` generates `AGENTS.md` and `.cursor/rules/*.mdc` from `CLAUDE.md` and the repo's skills —
    one law, every tool (D-002) — deterministically, so `--check` is a gate. `--target` is handed to
    the ledger's edges table rather than read a second time.
  - `discover` reads the findings a repo's own config already produces into `fixShape` candidates and
    writes nothing.
  - `skills list|lock|audit` pins skills by content hash in during.day's lock shape, and the audit
    fails on drift, on a skill nobody pinned, and on an executable file inside a skill directory — the
    supply-chain class a hash over `SKILL.md` is blind to.
  
  The plugin gains a `cli` layer in the kit's own `.oxlintrc.json`: it may read the presets, the parity
  tool and the doctor's resolver, and no gate it fronts. Three walls and three doors are planted
  against in `dogfood.test.ts`.
- 75f613e: **`create-geonosis` — a third repo that passes its own gates on day one.** `create-geonosis <dir>
  --runtime pnpm|bun --backend medusa|sagaflow-cf|none --ui tiered-shadcn|atoms-only|none` writes a
  workspace with one catalog of shared versions, an `exports` map and no barrel in every package,
  `typecheck` + `lint` + `test` in EVERY workspace (each asking vitest for its own JSON report), a law
  under sixty lines, the five config files, a lefthook, a CI workflow with nothing switched off in it,
  an empty skills lock and a `.claude/settings.json` that installs the plugin.
  
  There is no default for the three answers that decide the shape of the tree. A default borrowed from
  dielime or during.day would be one repo's stack hardcoded into every repo this ever writes.
  
  - **The edges table is the one place the graph is written.** `docs/architecture.md` carries it, and
    the scaffold runs `geonosis-ledger sync --target turbo` and `--target layer-walls` over it, so
    turbo's boundaries and the linter's layers are generated from the same table and cannot drift.
  - **The baseline starts at zero, except where zero would be a lie**: `lawLineCount` starts at the
    measured length of the `CLAUDE.md` just written.
  - **`lint-corpus/`** is a reach corpus in the new repo's own vocabulary, for the three rules whose
    reach is repo-specific — `layer-walls`, `no-brand-names`, `plugin-route-namespaced` — because the
    plugin's shipped corpus says `acme` and `layers/core` and is no evidence about anybody else.
  
  `@geonosis/cli`'s `rulesFor` now takes a map of pre-built rule options instead of a brand, so `init`
  and the scaffold answer the same question in one place. The plugin gains a `create` layer, walled
  against every gate it configures; planted in `dogfood.test.ts`.
- 40cc71c: **Two fixtures that turned on the tree's install state, and the door's flag split.**
  
  `the command registry > answers 2 when the bin is not installed here` and `doctor drift > warns
  about a block whose package is not installed here` both named `@geonosis/testbed` while that package
  did not exist — green for a reason that was not the code, and red the day the testbed shipped. Both
  now name `@geonosis/definitely-absent`, which can never be installed: the registry case goes through
  `runBin` directly, and `checkDrift` takes the block→reader map as a parameter (`READERS` is
  exported) so a test can name a package no base will ever have. A new case asserts the inverse the
  old one could not: every package the registry fronts is a dependency of `@geonosis/cli`, so
  `findBin` finds all twelve.
  
  `geonosis observability` joins the registry as a **write** — a real sink is somebody else's project,
  and `kind` is now "something outside this process a reviewer would want to have approved", not only
  a tracked file. `@geonosis/testbed` and `@geonosis/observability` are dependencies of the CLI, so
  `geonosis testbed` resolves.
  
  `geonosis <cmd> --help` used to print the DOOR's usage and never run the bin: the whole line was
  scanned for `--help`. A flag before the command is the door's, everything after it is the command's.

### Patch Changes

- Updated dependencies [01f5782]
- Updated dependencies [e6a54d5]
- Updated dependencies [94a2376]
- Updated dependencies [f76cff8]
- Updated dependencies [9858ee5]
- Updated dependencies [c575f44]
- Updated dependencies [90d38ec]
- Updated dependencies [c418f91]
- Updated dependencies [110073d]
- Updated dependencies [45407ec]
- Updated dependencies [5f09ddc]
- Updated dependencies [48d9c43]
- Updated dependencies [60f4d8f]
- Updated dependencies [b501b1b]
- Updated dependencies [a1ec2a6]
- Updated dependencies [386b0da]
- Updated dependencies [2667db5]
- Updated dependencies [2d52a6b]
- Updated dependencies [befb61f]
- Updated dependencies [188de19]
- Updated dependencies [7a6a02a]
- Updated dependencies [291a129]
- Updated dependencies [950d188]
- Updated dependencies [6ec6393]
- Updated dependencies [b858fcc]
- Updated dependencies [2732831]
- Updated dependencies [eb78517]
- Updated dependencies [89c6769]
- Updated dependencies [b1157fc]
- Updated dependencies [b2d915f]
- Updated dependencies [f05374f]
- Updated dependencies [7762a01]
- Updated dependencies [ff9874b]
- Updated dependencies [9a4c825]
- Updated dependencies [063f928]
- Updated dependencies [c3675c6]
- Updated dependencies [48bce0c]
- Updated dependencies [461233c]
- Updated dependencies [14e3bc6]
- Updated dependencies [e48501b]
- Updated dependencies [eb7ef0d]
- Updated dependencies [eb7ef0d]
- Updated dependencies [eb7ef0d]
- Updated dependencies [f82fa4d]
- Updated dependencies [88d7bf6]
- Updated dependencies [2637a99]
- Updated dependencies [75f613e]
- Updated dependencies [7a6b019]
- Updated dependencies [40cc71c]
- Updated dependencies [0336070]
- Updated dependencies [f60a869]
- Updated dependencies [35adf9a]
- Updated dependencies [13bd54d]
- Updated dependencies [8006520]
- Updated dependencies [d1c8727]
- Updated dependencies [85b22b1]
- Updated dependencies [c479255]
- Updated dependencies [bc0bb33]
- Updated dependencies [7e8d2c1]
- Updated dependencies [cd089cb]
  - @geonosis/verify-arch@1.0.0
  - @geonosis/ratchet@1.0.0
  - @geonosis/oxlint-plugin-biological-architecture@1.0.0
  - @geonosis/walk@1.0.0
  - @geonosis/lint-parity@1.0.0
  - @geonosis/doctor@1.0.0
  - @geonosis/verify@1.0.0
  - @geonosis/ledger@1.0.0
  - @geonosis/observability@1.0.0
  - @geonosis/review@1.0.0
  - @geonosis/visual-diff@1.0.0
  - @geonosis/testbed@1.0.0
