# @geonosis/walk

## 3.7.0

### Minor Changes

- 281381c: The walk gains an `axe` probe through `@axe-core/playwright`, an optional peer: `critical` and `serious` violations are findings of class `accessibility-error` (blocking, major), `moderate` and `minor` of class `accessibility-warning`, and a missing peer exits 2 naming `npm i -D @axe-core/playwright` (#215, plan 049 T3). The report counts both classes whenever `axe` ran, and the summary names both beside it. The `walkFindings` counter takes `classes: ["accessibility-error"]` and `["accessibility-warning"]`, so a gate can count the errors without the warnings.
- 2e0aae2: A URL entry takes `scrollTo` and `waitFor`: the walk scrolls to the first and waits for the second before any probe reads the page, and exits 2 naming the selector and the URL when it never appears (#173). The report records `gpu` and what the browser answered for WebGL, caveat, renderer and vendor, so two reports of one page can be compared (#172). The summary names each probe that ran by its id, with its class where the two differ (#174).

### Patch Changes

- 8eda0d0: A refusal that names a command spells it the way it was reached. Run through the `geonosis` door, `geonosis walk` and `geonosis review` refuse an unknown flag with `run geonosis walk --help` and `run geonosis review --help`, and `geonosis verify-arch --check` names `geonosis verify-arch --format … --output …` as the command that rewrites a stale drawing; run by their own bins they name those bins as before. The `walkFindings` counter with no walk report says to run `geonosis walk`. Each named the tool's own bin, which under pnpm is a command only where its package is a direct dependency (#68).
- 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).
- cc48e0e: The `walkFindings` counter takes `classes: ["content-integrity"]`, the class of the walk's four newest probes (`thin-page`, `empty-section`, `money-format`, `orphan-url`). Before, the counter's own list of classes lacked it, so those findings could be counted only in the total. A test in the kit's repository holds the counter's list to the walk's own list of classes, the one its exported `DefectClass` type is drawn from. The walk's package description counts fourteen probes, thirteen computed-DOM readings and axe's accessibility rules; it counted eight.
- Updated dependencies [1830b16]
- Updated dependencies [1dabee8]
- Updated dependencies [74147f7]
- Updated dependencies [b505542]
  - @geonosis/base@3.7.0

## 3.6.1

This package had no change of its own in 3.6.1. What the group changed under that number is in `GROUP-CHANGELOG.md`, in the `@geonosis/cli` package.

### Patch Changes

- Updated dependencies [ac7f890]
  - @geonosis/base@3.6.1

## 3.6.0

This package had no change of its own in 3.6.0. What the group changed under that number is in `GROUP-CHANGELOG.md`, in the `@geonosis/cli` package.

### Patch Changes

- Updated dependencies [630d44c]
- Updated dependencies [e65a3b0]
- Updated dependencies [f275d25]
  - @geonosis/base@3.6.0

## 3.5.0

### Minor Changes

- 2cc5f78: The walk launches Playwright's full Chromium (`channel: 'chromium'`), not its headless shell (#155). Under Playwright 1.64.0 and Chromium 156 the shell grants WebGL that asks `failIfMajorPerformanceCaveat` in SwiftShader even under `--disable-gpu`, so a walk saw 3D no visitor without a graphics processor gets. `walk.gpu: false` and `--no-gpu` walk without one; the WebGL caveat is then refused, as Chrome refuses it. `npx playwright install chromium` installs the full build beside the shell.

### Patch Changes

- Updated dependencies [2cc5f78]
- Updated dependencies [b01150f]
  - @geonosis/base@3.5.0

## 3.4.1

### Patch Changes

- @geonosis/base@3.4.1

## 3.4.0

### 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.
- Updated dependencies [ebb216e]
- Updated dependencies [7492bfa]
- Updated dependencies [13e1386]
  - @geonosis/base@3.4.0

## 3.3.0

### Minor Changes

- fb08b28: `walk.versionKey` and `--version-key <key>` send `Cloudflare-Workers-Version-Key` with every request to the origin of each walked page (#64). During a gradual deployment on Workers each request is otherwise routed to a version by chance, so a walk can read HTML from one version and ask the other for its content-hashed assets. The header goes on the page's own requests through a route scoped to that origin, and on the HEAD and GET requests `link-integrity` makes to it (`ProbeContext.headers`); another origin's requests are left alone, because a custom header sends them through a CORS preflight.
- fb08b28: A page that answers 400 or worse is walked instead of aborting the run (#61). `walk()` threw for any status of 400 or more before a probe ran, so the run exited 2 with no report, the pages already walked lost their findings, and `error-page-status`'s `honestFrom` could never take effect. Every page that answered is now walked, each probe is handed the status, and the report records it per page (`status`). The status a page must answer is declared in the config, `walk.urls: [{ "url": …, "status": 404 }]`, and a page that answers anything else is a finding: `link-integrity` for a broken link in the walk list (an undeclared 400 or worse, or a declared 200 that answered an error) and `error-page-status` for a soft 404 (a declared error that answered 200). Exit 2 stays for a page that answered nothing or could not be opened; that stops the walk, names the URL, and writes the pages walked so far to `<report>.partial.json` while the report the ratchet reads stays absent. `walk()` takes `expected`, throws `WalkStopped` (a `WalkError` carrying the partial report), and `PageReport` gains `status`.

### Patch Changes

- 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).
- Updated dependencies [fb08b28]
  - @geonosis/base@3.3.0

## 3.2.0

### 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.
- 58eaf3a: `link-integrity` refuses an `ignore` pattern that is not a regular expression before it reads a link, naming the pattern, and reports why a target could not be reached rather than `answered 599`.
- deef511: The README's account of what the probes reach is recounted for the thirteen it ships: of the audit's 36 defects, six reproduce from a probe alone, sixteen partially and fourteen by none (it said four, fourteen and eighteen, for the first eight).
- Updated dependencies [f5632b7]
  - @geonosis/base@3.2.0

## 3.1.0

No changes in this release.

## 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.

## 2.13.0

## 2.12.0

## 2.11.1

## 2.11.0

### 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 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.

## 2.10.0

## 2.9.0

## 2.8.0

## 2.7.0

## 2.6.1

## 2.6.0

## 2.5.3

## 2.5.2

## 2.5.1

## 2.5.0

## 2.4.3

## 2.4.2

## 2.4.1

## 2.4.0

## 2.3.1

## 2.3.0

### Minor Changes

- 3dac9a7: **`content-integrity`, the tenth walk class, and its four probes (#43).** A page that renders
  correctly and says nothing was being filed under `fabricated-claim`'s forbidden-string engine, which
  is one class borrowing another's mechanism. `thin-page` counts the words a reader is shown against a
  floor the repo sets; `empty-section` names a container carrying a heading and no body; `money-format`
  names a price in a shape the repo does not write; `orphan-url` names a walked page nothing links to.
  
  The last one needed a report-level contract, so `Probe` gains an optional `finish` — the reading no
  single page can make — whose findings are filed against the page they name. Three of the four refuse
  at load without the repo fact they cannot mean anything without (D-031).
- 3dac9a7: **The walk prints its denominator (#96).** `0 finding(s)` over three of nine probes was the same
  sentence a fully configured clean walk prints. The summary now carries `N of M probe(s) ran` beside
  the pages and the findings, and names the probes that were never looked for.

### Patch Changes

- 3dac9a7: **One documented spelling (#90).** Every README of a package the metapackage fronts now names
  `geonosis <tool>` — the door that pins the whole toolchain at one version — beside the bare bin, and
  a `tooling/` test holds it. `#230`'s stamp test lands with it: every flag `docs/orchestration.md`'s
  adoption loop names has to carry the version it first ships in, because the loop once told a
  consumer to run a flag the published version did not have.

## 2.2.0

## 2.1.0

### Patch Changes

- e0da9a3: **D-060 made mechanical, and the sweep it found (#220).** A published README or dist comment may name a consumer as the SOURCE of a pattern — that is attribution of the user's own products — and may not describe what is inside one. `tooling/provenance.ts` reads every publishable package's README and `dist/`, and fails on a consumer's name followed within the sentence by an internals noun (table, plane, column, schema, migration, incident, outage, postmortem, `apps/`, `packages/`) with no provenance phrase between them; the consumer names come from `geonosis.json`'s declared smoke snapshots, never from a list of its own — the kit's `no-brand-names` rule refuses a brand written into this repo, so a name enters that vocabulary only by being declared a consumer. It found nineteen sentences across nine packages — their file paths, their table and selector names, their line counts, their incident — and every one is reworded rather than stripped of its attribution.

## 2.0.0

### Patch Changes

- 4b61257: **`geonosis` — one manifest line pins the toolchain.** `pnpm add -D geonosis` (or `bun add -d geonosis`) installs `@geonosis/cli` and every gate it runs, all on one version, and ships no bin of its own. What it brings is exported as data — `TOOLCHAIN`, `BY_NAME`, `OPTIONAL_BINARIES` — and checked against the workspace by its own test, so a package added to the group cannot go missing from the list quietly.
  
  #73's lesson is a gate here: every peer of every installed package must be optional, or named in `REQUIRED_PEERS` with the reason every consumer pays for it (`oxlint`, `zod`, `better-result`). It caught a live one — `@geonosis/walk` declared `playwright` as a REQUIRED peer while its own code already imports it dynamically and refuses by name. Measured on a scratch consumer against a local registry: **bun 1.4.0 installs a non-optional peer without being asked; pnpm 11.8.0 does not** — so `bun add @geonosis/cli` was pulling a browser driver into repos that never walk anything. `playwright` is now an optional peer of `@geonosis/walk`.

## 1.4.0

## 1.3.0

### Minor Changes

- 2d1d841: **`geonosis-walk --help` answered "unknown option --help" at exit 2 (#66).** It now prints its
  usage — the flags, and the three exit codes that were documented only in a code comment — at exit 0
  for `--help`/`-h`, and the unknown-option refusal points at it.
  
  **It also answers `--print-config-shape` (#75)**, assembled from the same `KNOWN` set the reader refuses against.

## 1.2.0

## 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").

## 1.0.0

### Major Changes

- 9858ee5: `error-page-status`, a ninth probe from a production incident: a page whose body is an error surface
  and whose status is healthy. Every curl-style health check, uptime monitor and load balancer reads
  such a page as fine while nobody can use it. The status comes from the page's own response, so
  `ProbeContext` gains `status` — a second request would ask a different question of a server that may
  not answer twice the same way. `patterns` is required (D-031); a page that answered 400 or worse is
  a server telling the truth, and the walk refuses that URL on its own. `walkFindings` counts the new
  class.
- cd089cb: `@geonosis/walk`: the customer walk as a gate. Eight computed-DOM probes — light-on-light,
  placeholder-asset, link-integrity, fabricated-claim, stub-only-entity, fake-session, ops-leakage,
  buy-box-above-fold — over a list of URLs, with a JSON report and three exit codes: 0 clean, 1 found
  something, 2 could not run. Five of the eight refuse the run when the repo has not given them the
  list they cannot mean anything without (D-031). Playwright is a peer dependency; every probe is
  proved against a fixture page that fires and one that passes, through a real browser.
