Skip to content

v0.10.0

Choose a tag to compare

@qwerfunch qwerfunch released this 10 Sep 02:56
· 9 commits to main since this release
8303073

In one line: Spec schema 0.2 — a feature says what it is for before what it does, every acceptance criterion has an address you can point at, a test claims a criterion by naming it in its own title, one compiled model answers questions about how the pieces relate, each level of assurance has a named check profile recorded in a new attestation format, and a reviewed path carries an old project across.

Heads-up: a project still on the old spec format should commit its work first — the migration refuses to touch a path with uncommitted changes on it — then run clad migrate --to 0.2 to preview the rewrite, apply it once the decisions it lists have been reviewed, and re-prove the tree with clad check --tier=pre-push. One of those decisions asks whether your already-completed features may carry their existing proof forward. Answer no and they carry nothing: each finished feature stays red until one of its test titles names the criterion it covers. That answer is recorded once — changing your mind means undoing the migration and applying it again. The headless loop is gone — start the server with clad serve and let your AI host work the feature cycle. Moving the generated files into one folder is opt-in through clad relocate-generated; leave it alone and the existing layout keeps working. And the pre-push check rewrites the sealed record of what was verified every time it passes, so commit those files along with your change. One detail worth knowing before you write tests: the tag that says which acceptance criterion a test covers has to come at the very start of the test's title — a tag placed anywhere else in the title is not read, and the criterion it names is still counted as unproven.

Added

  • Spec schema 0.2. A feature states its purpose first, every acceptance criterion carries an address you can point at, and a test claims a criterion by naming it in the test title. Behind that: a compiler with typed registries and a typed reader, transactional spec editing, a preview of the migration from 0.1, a kernel that carries proof and portable evidence, and five verification profiles — feedback, checkpoint, completion, push, release — recorded in a third-generation attestation file.
  • One compiled model now answers the questions that used to be asked of four, with layers for what the spec declares, what the documents link, what the source references, and which tests the current gate actually observed. The gate now hands the graph a sealed record of test cases instead of raw report bytes.
  • The count sync covers feature counts too. node scripts/test-count.mjs --write refreshes the README feature totals alongside the test totals.
  • clad relocate-generated moves the generated files under spec/generated/. It previews the move by default; --apply performs it as one recoverable transaction. This is opt-in — the layout you have today stays fully supported.
  • A schema 0.2 workspace explains its own generated files. spec/generated/README.md is projected from the registry of generated artifacts and names where each one lives now and where relocation would put it.
  • A release gate for the 0.2 validation work. The validation ledger declares which scenarios block the 0.10.0 release, and npm run validate:spec-0.2:release exits nonzero while any of them lacks discriminating evidence. Evidence produced on a reference host counts only when its recorded receipt is signed by an issuer registered in the trust snapshot stored beside it. Both reference-host cycles for this release — one on Claude Code, one on Codex — were driven by automation rather than by a person working at a keyboard, and the confirmation step before each sign-off was answered by that automation on the maintainer's instruction. The signatures and the offline verification are real; what was not exercised, and so is not claimed, is either host's own confirmation form.
  • The release was measured against the engine it replaces, and against no engine at all. Three arms ran the same task on the same host and the same model, three times each: an assistant with no engine, released 0.9.4, and this build. On the deterministic table, 0.9.4 lets a warning-level drift finding through a gate that was not asked to be strict, accepts an acceptance criterion with no statement, and accepts the binding field this release no longer reads — this release refuses all three, and lowers the depth ceiling on graph questions, refusing requests above it. Live, both engines carried the work to an honest finish 3 of 3, at a median estimated $1.00 against $1.23 and 21 turns against 27; those are list-price estimates, not amounts billed. Code quality, coverage and a hidden oracle came out the same across all three arms, so this release claims no better code. The record is docs/ab-evaluation/case-version-abc-094-vs-0100.md.

Changed

  • Completeness is judged from structure alone. Scope and closure derive from structural relations; an unresolved piece of evidence or an oracle reference that does not resolve stays a visible negative fact about its own criterion instead of making every verification profile unresolved.
  • The authoritative profiles block on warnings. Completion, push and release refuse on warn-level drift findings; --strict remains an explicit escalation on top.
  • A project's own instructions now say how a test claims a criterion. The managed sections in AGENTS.md and CLAUDE.md, the gate's report of a criterion nothing has proven, the guidance it prints when tests are missing, and the message that refuses the old way of binding all name the same thing: on the new spec format, a test claims a criterion by carrying that criterion's tag at the very start of its own title. Until now those surfaces still described the previous format's way of doing it, so a project on the new format was being told to do something the gate no longer reads. A project still on the old format sees its wording unchanged, byte for byte.
  • An archived feature whose successor is not done yet reports its surviving modules as information rather than a problem, until that successor completes.
  • clad done reports how independently the work was verified. In a schema 0.2 workspace it states the independence label recorded for that completion. By default the label only annotates; set independence_policy: require and it decides — a sign-off by the person who implemented the feature no longer counts as independent review, and a completion whose authors cannot be identified is refused rather than passed. The old spec format keeps its previous label unchanged.

Removed

  • The experimental headless loop and its run command. Nothing ever ran it — three and a half months of recorded sessions contain zero runs — and it never learned to write code, so it could only report honest failure. Start the server with clad serve and let your AI host work the feature cycle instead; that is the path everything else already used.
  • The parts that existed only to serve that loop: the agent adapters, the crash-postmortem recorder, and the progress-line renderer. The host transport the onboarding scan uses is untouched, and so is the Anthropic SDK dependency behind its API-key fallback.
  • The run skill, and its copies in the Claude Code, Codex, and Antigravity plugin folders.

Fixed

  • The host support table was refreshed against live runs for this release. Claude Code, Codex and Cursor answered every check — Cursor, which the readme had not claimed before, is now recorded as working. Gemini still fails, and Antigravity — which the table previously recorded as working — now times out on every check, so the readme no longer claims it as verified.
  • Graph code no longer reaches into gate code, restoring the architecture rule that keeps the two apart.
  • A renamed test keeps its binding. Bindings carried forward by the migration and then invalidated by a title edit are promoted to live tokens instead of failing silently.
  • Patched dependencies. The MCP SDK's transitive fast-uri, qs, and side-channel packages move to their patched releases, so npm audit reports no known vulnerabilities. A later batch, reported on 2026-09-09, moves the web framework the MCP server carries and the YAML reader and test runner used by the development tools to their patched releases as well, so the audit stays clean.
  • A workspace holding a signed review could never record a verification. The gate sealed the record of what it verified without counting the reviews on disk, while the writer counted them, so the two never matched: the check finished green, wrote nothing, said nothing, and clad done refused with a cause it could not name. Both now read the same set, the freshness check reads it too, and a refusal names the guard that refused.
  • Asking for a different level of assurance for one run now says why it was refused. Requesting a level the project does not allow — anything below the level it is set to, or a stronger one anywhere except a single feature's completion check — used to end in a red result with no cause printed anywhere, every check apparently green. The refusal now names its reason before anything runs; a run without the option is untouched.
  • A receipt imported on the command line is now checked against the project's registered signers, exactly the way it is when your AI host imports one. Until now every receipt was filed as an unverified claim, whether it was genuine, altered, or signed by someone the project never registered — an altered one is now refused and nothing is stored.
  • An attestation stamped on a working machine now matches the one a clean checkout computes. A desktop metadata file left behind by a file browser, or an ignored fixture sitting inside a sealed folder, used to be sealed alongside the project's own files, so the record a green local check wrote was already stale on every other machine — most visibly in continuous integration, where the same commit came back red. The record now covers what the repository actually tracks, so a check that passes on your machine passes on a fresh clone. Files kept inside a nested repository or a submodule are not part of that tracked content either, so a module pointing into one is now treated as absent and the check refuses rather than sealing foreign files.