How we work
One source of truth per fact, generated rather than checked — and why this wiki is built that way too.
Automation Forge is nine repositories, thirty-seven plugins and twenty-four public source mirrors. The failure mode is never "the code is wrong". It is a true statement in one repository and a stale copy of it in three others.
Almost everything about how we work exists to stop that.
Derive, don't check
The instinct, when a number appears in four files, is to write a checker.
We did. It caught drift after it happened, which is to say after somebody had already published the wrong figure. A version number typed in four places with a checker watching them still drifted three times in a single day.
So the rule changed: when you find yourself about to write a checker for a number, write a generator instead.
A plugin's version lives in its descriptor. The README banner is generated from it. The tool count is generated by counting tools. The agent-facing version is read at runtime from the plugin descriptor, so there is no window between a bump and a fix in which an agent is told something false.
Generated facts are written into marked regions inside hand-written prose:
<!-- forge:version -->**Version 0.2.1. Beta.**<!-- /forge:version -->
<!-- forge:tools -->45 tools<!-- /forge:tools -->Everything outside the markers is untouched, so documents keep their voice and stop carrying numbers anyone has to maintain. A judgement inside a region survives regeneration — the maturity word ("Beta", "Experimental") is read back out and preserved, and only the number is generated.
This wiki follows the same rule. No page here types a version, a download URL, a file size or a release date; all of it is read from the generated release manifest. The changelogs are the extreme case — one page per plugin, hundreds of version numbers, every one of them generated.
The code beats every document about it
In order of authority:
The code
Beats every document describing it, including this one.
The register
One file decides each plugin's set, role, licence tier and what may leave the private repository. It is the single place that decides what ships.
The generated manifest
Assembled by CI from the register, the plugin descriptors and the published releases. Never edited by hand.
Hand-written prose
This wiki, the READMEs, the marketing site. Useful, opinionated, and the most likely thing in the list to be out of date.
If this wiki and the plugin disagree, the plugin is right. That is not modesty; it is a routing instruction. Report it as an issue rather than editing the prose to match a guess.
Claims rot, so they carry their conditions
Numbers, statuses, counts and "not yet built" all age badly. Three rules we learned by publishing things that were true in a way nobody could use:
- A number is published with the condition it holds under. One local motion route runs in about fourteen seconds with a particular precision setting and five to seven minutes without it, because the prompt encoder is the slow part. Both figures are true; neither is true alone.
- A measurement names its route. A face-solve ratio measured end to end on a hosted provider is not the figure for the local CPU route. Publishing one against the other's description is the defect, even though both numbers are real.
- Strike a closed item in the same change that closes it. A register that lags is worse than no register, because it invites the next person to fix what is already fixed.
And a fourth, about intent: deliberate decisions get recorded as decisions, not left looking like findings. An open finding invites someone to act on it. A trade-off we made on purpose, written up as though it were a bug, wastes exactly one afternoon per reader.
Merging and shipping are different decisions
A change moves through the repositories in dependency order — code first, then the generated artefacts, then the public docs, then the site — one pull request per repository.
The release notes are written in the same pull request as the change, because those notes become the GitHub release body and an unattended publisher posts them to Discord within about fifteen minutes of a release. There is no later moment to write them in.
But the tag comes after the merge, as a separate deliberate act. Merging means the work is correct. Tagging means it should reach customers today. Those are different judgements and automating the second into the first removes the only place the second gets made.
Honesty as a working practice
Principle 12 of the manifesto says honesty is the brand. In daily practice that mostly means being specific about status:
- Working, beta, developer preview, prototype, in development and planned are different statements, and we say which one applies.
- A plugin whose source is closed says so. A plugin that is free but closed is not described as open source. See open, free and paid.
- Nothing is on Fab. "Fab" is a licensing tier in our register, not a shop we are listed on, and we do not write that a plugin is available there until a listing exists.
Where this wiki fits
Honestly: it is now one more place a claim about a plugin can go stale.
Version drift is impossible here by construction — every version, licence tier and release note is generated. Prose drift is not. A page saying a step runs locally, after that step moved into a container, is exactly the failure this whole apparatus exists to prevent, and nothing automated catches it.
That is a known, accepted cost of having documentation at all. It is on the audit list rather than solved, and saying so is the practice working as intended.