Spec Forge: Beyond Vibes to Behaviorally Complete Design Specs

wakko6661 pts0 comments

GitHub - blentz/spec-forge · GitHub

/" data-turbo-transient="true" />

Skip to content

Type / to search

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

blentz

spec-forge

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>46 Commits<br>46 Commits

assets

assets

references

references

workflows

workflows

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

SKILL.md

SKILL.md

View all files

Repository files navigation

spec-forge

A Claude Code skill that adversarially certifies a specification as behaviorally<br>complete — before any code is written.

The goal is not a longer spec. It is a spec with no observable residual freedom:

Spec S is behaviorally complete iff every implementation satisfying S is<br>observationally equivalent to every other, under a declared observation alphabet Σ.

Names, formatting, and internal structure are not in Σ, so a complete spec does not<br>have to mention them. What it must not do is leave a coding agent guessing about<br>behavior that Σ can see.

Why this exists

If you hand a spec to a coding agent and it stalls — asking questions, or worse,<br>silently inventing unstated behavior — the spec was underdetermined. That is<br>measurable without rendering the application:

A spec is underdetermined exactly where an adversary can exhibit two implementations<br>that both satisfy it and diverge on Σ.

That divergence is the gap, it is localized, and it is already a test case. spec-forge<br>runs adversaries to produce those distinguishing pairs, has a human ratify each one, and<br>turns the ratified answers into clauses and into the acceptance suite. You never author<br>the acceptance suite; you harvest it from the ambiguity resolution.

Two limits are stated up front, because pretending otherwise would be a lie:

The limit is Rice, not Gödel. "Is S complete?" is undecidable in general, so the<br>process is adversarial and statistical and issues a certificate , never a proof. The<br>certificate has a mandatory RESIDUALS section.

Completeness is relative to (agent class A, toolchain T).<br>spec_bits + prior_bits + toolchain_bits ≥ behavioral_entropy. A non-zero integer type<br>discharges "quantity is always ≥ 1" totally and unspoofably; a language without that type<br>needs prose plus a runtime validator plus a property test to get the same teeth. The same<br>spec can be complete in Rust and incomplete in Python, so the certificate names A and T.

Acceptance criterion

Spec completeness = the coding agent's question count + its uncited-decision count.<br>Both zero, or you are not done.

Not "a human read it and liked it." That is not a gate, it is a chore, and it is the first<br>thing anyone skips.

Installing

The repo root is the skill. Put it where Claude Code looks for skills:

git clone https://github.com/blentz/spec-forge ~/.claude/skills/spec-forge

Then ask Claude something like "is this spec complete?" or "certify this spec" and the<br>skill triggers. Python assets are stdlib-only; spec_gate.sh needs bash and python3.

Prerequisite: the Workflow tool. Every phase from 1 on is a Workflow({ scriptPath })<br>call, and it is not delegable — subagents do not get the tool, so you cannot hand this<br>skill to a general-purpose agent and walk away. Drive it from the main loop.

The workflows/*.js files are Workflow scripts, not Node programs. node workflows/ontology.js<br>will fail: agent(), parallel(), and phase() are injected by the Workflow runtime.

The pipeline

Phase 0 OBSERVATION.md declare Σ — what counts as observable<br>Phase 0.5 SPEC.md CLAUSIFY: prose → S-NNN clauses<br>Phase 1 ONTOLOGY.md subject × stimulus grid; the adversary work-list<br>Phase 2 WITNESSES.md underdetermination loop — run until DRY ←──────┐<br>Phase 2b contradiction contradiction hunter — run until CLEAN │<br>Phase 2c ratification did the answer actually ANSWER? earns `seen` │<br>Phase 3 spec-mutation anti-vacuity: every clause must carry bits │<br>Phase 4 CERTIFICATE.md Σ, A, T, dry rounds, RESIDUALS │<br>Phase 5 DISCHARGE.md route each clause to its cheapest enforcement rung │<br>Phase 6 build loop harness first, implementation last ─────────────────┘<br>uncited decision = new witness

Phase 1 is 3% of the spend and finds the worst defects — including entities the author never<br>named, which cannot show up as a MISSING cell because they have no cell. Never skip it.

Driving it

Use the driver. Do not drive it by hand.

assets/forge.py init spec/ # scaffold EMPTY templates<br>assets/forge.py status spec/ # loop state, Σ lint, void counters<br>assets/forge.py next spec/ # what to run now, and why<br>assets/forge.py next spec/ --sigma # the `sigma` arg every...

spec phase forge complete assets skill

Related Articles