Changelog · Wherefore 0.11.0
Every release, newest first.
Built from the release this site pins, so a release is here the moment the site moves to it - and the build stops if a feature it ships has no words on this site.
-
The map says what it is
What nobody regenerates is written, not built - by a person or by an agent - and the map says so, never 'by hand'. wherefore graph --home puts a way back to the site on it, and a theme gets two marks beside the accent, so a brand whose accent is a highlighter writes with its ink and marks with the accent.
$ wherefore graph --home https://fernhollow.example/ Fernhollow 15 files: 4 generated by 4 scripts, 10 written, not built, 1 captured; 6 reads traced; wrote wherefore-graph.htmlWhat it printed -
The notice reads nothing new
The gate's palette notice counts colours only in the files the build made - which the gate wrote and compared anyway - so a courtesy never widens what the gate opens. The first client records every file its gate reads; 0.10.0 had broken that promise.
$ wherefore gate NOTICE colours are said in 2 files the build made and no palette is declared: `wherefore check palette` would hold them to one source. Declare `palette` in wherefore.json - its `source`, the JSON file the brand lives in - or decline it, {"none": why}.What it printed -
One palette
A brand is a fact like a price. wherefore check palette reads every tracked text file and fails a colour that is not one the brand's source holds, unless the file says, with why, whose colours they are. On by default: the gate says when colours are said in several files and no palette is declared.
$ wherefore check palette ::error::a colour is said that brand.json does not hold - the brand, said twice: site/page.css:3: #FF3355 - a colour that is not one of brand.json'sWhat it printed What arrived
- One palette Your brand lives in one file. Type a colour anywhere else and the build names the file and the line, unless the file says, with a reason, that the colour is somebody else's.
-
The map in the corpus's own colours
wherefore graph --theme CSS puts a corpus's own stylesheet where the page's light and dark palettes were, so the map reads the brand's custom properties and carries no second palette typed into the engine.
$ wherefore graph 15 files: 4 generated by 4 scripts, 10 written by hand, 1 captured; 6 reads traced; wrote wherefore-graph.htmlWhat it printed -
The map credits itself
A corpus may publish its own map: a run generator that is wherefore graph, so the page is built and judged like any other file. Under the gate it runs; under wherefore graph it is credited with the files it names rather than run, so the map never maps itself without end.
$ wherefore graph 15 files: 4 generated by 4 scripts, 10 written by hand, 1 captured; 6 reads traced; wrote wherefore-graph.htmlWhat it printed -
What builds what
wherefore graph runs every generator once, traces what each reads and writes, and draws the chain as one self-contained page: every source, the scripts that read it, and everything they make. Choose a source to see what changes with it. It classifies every file as the gate does, and puts the tree back as it found it.
$ wherefore graph 15 files: 4 generated by 4 scripts, 10 written by hand, 1 captured; 6 reads traced; wrote wherefore-graph.htmlWhat it printed What arrived
- What builds what A page for every repository: each file, how it is made, and what changes when a source does. One command draws it, and changes nothing.
-
A generator can be any command
A generator can be any program - node, a shell script, a CAD export - declared by run, its command as a list of words, with no Python wrapper. What it writes is seen by comparing the tree before and after it runs, on the ctime no process can set back, so it is held exactly as strictly as a Python generator.
$ wherefore list 1 generators, in order ok sh site.sh sh site.sh 1 tracked files site/index.html, the landing page 1 tracked writes, 0 writes to paths git does not trackWhat it printed -
What a pre-publication review found
The first release for PyPI. When what the engine reads is not what it expected - an answer cut short, a pointer that is not one, a file that is not JSON, a redirect to another host - it now says so in words instead of a traceback or a wrong answer, and a scan of a site fetches no more than it is told to.
$ wherefore check upstream ::error::wherefore.json: captured group 'pack' in wherefore.json: `upstream.read.json` is a JSON pointer - "" for the whole document, or a path that starts with "/", such as "/version"; it says 'release/version'What it printed -
Every surface, held to the source
The skill now asks where else the product is described and sets each surface up to pin the source and fail its build on a feature it does not say. A copy taken from somewhere that cannot be pinned - another site, another product - says where it came from, and wherefore check upstream fails when that source moves. Every release is said once, as data, so a changelog is built rather than kept.
$ wherefore init wrote ~/fernhollow/wherefore.json wrote .claude/skills/wherefore/ (Claude Code) and .agents/skills/wherefore/ (Codex): the skill a coding agent here reads … Then every place the product is described - a site, the docs, another repository - pins the one that decides it, and fails its build on a feature it does not say: start.md, "Every surface".What it printed What arrived
- Derived from elsewhere Copied something you can't pin, like a partner's spec sheet? The deploy fails the day its source changes.
-
The skill reaches Codex
The skill is written where Codex reads it as well as Claude Code, and held to the release in both places. What the engine does is said once, as data, so a page that describes the product keeps up or its build stops.
$ wherefore init wrote ~/fernhollow/wherefore.json wrote .claude/skills/wherefore/ (Claude Code) and .agents/skills/wherefore/ (Codex): the skill a coding agent here reads Commit them. Then ask your agent to set up Wherefore: the skill's start.md is how. From the first build on, the skill is regenerated from the release this repository pins.What it printed -
Scan: the first win, with no setup
Point wherefore scan at a built site, a docs folder or a live address, and it reports every value stated more than one way. It needs no configuration, and it would rather miss a disagreement than invent one.
$ wherefore scan . 4 stated values in 4 files or pages; 1 statement whose copies disagree "start your {} day free" - said 4 times, 2 ways 14 3x docs/start.md:1, site/index.html:1, site/pricing.html:1 30 1x help/billing.md:1What it printed What arrived
- Scan Point it at your site or docs: it finds every value you state more than one way, and where the copies disagree.
-
What a fresh review found
Every way a fresh review found for the gate to pass when it should fail, reproduced, fixed, and held by a test that plants it. A flag a command does not take is refused, not ignored. Ready to be published as open source, under Apache-2.0.
$ wherefore gate --kep ::error::the gate does not take --kep usage: wherefore gate [--keep] wherefore gate --restamp GROUPWhat it printed -
The skill ships with the engine
A coding agent learns the rules from the release itself, and starts a corpus with you: one fact, end to end. The copy in a repository is generated, so it moves with the pin.
$ wherefore init wrote ~/fernhollow/wherefore.json wrote ~/fernhollow/.claude/skills/wherefore/, the skill every coding agent here reads Commit both. Then ask your agent to set up Wherefore: the skill's start.md is how. From the first build on, the skill is regenerated from the release this repository pins.What it printed What arrived
- The skill, for Claude Code and Codex Claude Code or Codex learns the rules from a skill that ships with each release.
-
Wherefore on Wherefore
The engine became a client of itself. Its commands and its principles are said once, its own README is built from them, and it is judged by the release before it, the way a compiler builds itself.
$ wherefore --help wherefore - the command line. wherefore init [DIR] write a wherefore.json that declares nothing yet wherefore gate [--keep] every tracked file classified, every generated one current; puts the tree back unless --keep … The commands, and what each does, are said once, in commands.json beside this file; `wherefore --help` prints them from there, and so does the README.What it printed -
The first release
The machinery that keeps a hardware company's documents true, moved out of the pendulum it was built for: generators, the coverage gate, proofs, retired facts and reach, proved against a fictional company.
$ wherefore gate 15 tracked files; 4 generators generated 4 written by a generator during this run authored 10 declared a source in wherefore.json captured 1 declared hand-made, and stamped … every tracked file is classified, and every generated one was written during this run and matches what is committedWhat it printed What arrived
- Start a corpus One command starts a repository; the skill walks your agent through the first fact.
- The gate On every push, each file must be built from the source, written by a person for a stated reason, or a capture stamped with what it shows. Anything else stops the change, and says why.
- The build Every asset rebuilt from the source, the same way every time, so you see exactly what a change moves.
- Proofs No check is trusted until it has failed: each proof plants the fault its check exists to catch.
- Retired facts Retire an old price, name or limit once, and nothing a person reads may say it again.
- Reach Wherefore changes each fact, one at a time, and checks that everything stating it changes too.
- Claims Give a claim like “SOC 2 certified” a rule, and no page can say more than the rule allows.
- The pre-push hook A push that would ship a stale document stops before it leaves your machine.