SpecLine โ a spec-driven production line for AI-assisted engineering: PRD -> spec -> plan -> atomic task packets -> gated code, with token-lean context hygiene and a compiled-decision handoff to Harness Software Factory (HSF).
Project description
SpecLine ๐ญ
A spec-driven production line for AI coding agents. PRD โ spec โ plan โ atomic task packets โ gated code โ production, with token-lean context hygiene enforced by tooling instead of discipline, and a compiled-decision handoff to Harness Software Factory for the logic that should never be improvised twice.
Works with Claude Code, Codex, and any agent harness โ one command wires it in.
Workflow at a glance
flowchart LR
A["PRD or rough idea"] --> B["Draft spec"]
B --> C["Strict contract check"]
C -->|"blocks ambiguity"| B
C --> D["Gate spec and seal hash"]
D --> E["Create atomic plan"]
E --> F["Emit one task packet"]
F --> G["Agent builds exactly one slice"]
G --> H["Audit code against packet"]
H -->|"drift found"| F
H --> I["Gate code and update receipts"]
I --> J{"Decision table?"}
J -->|"yes"| K["Handoff to HSF"]
J -->|"no"| L["Ready for ForgeLine or PR"]
PRD โโ> Spec (EARS+Gherkin) โโ> Gate โโ> Plan (atomic tasks) โโ> Gate
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโ Ralph Wiggum Loop โโโ Decision tables in the spec
โ specline loop next โ โโ> specline handoff
โ โ token-budgeted โ โโ> HSF compiles them ONCE into
โ TASK PACKET โ gated, deterministic code
โ agent does ONE task โ (zero tokens per decision, forever)
โ specline loop done โ
โ โ verify + seal โ
โโโโโ context reset โโโโโ โโ> Gate โโ> ship
Why
Vibe coding hits the wall around four files: context pollution, intent drift, API hallucinations. The fixes are known โ specs as source of truth, constitutions, vertical slices, context resets โ but they live in blog posts as discipline. SpecLine turns them into tooling: linted, gated, hash-sealed, and receipt-audited, so the discipline holds at 2am too.
Quickstart (5 minutes, no API keys)
pip install -e ".[dev]"
specline init # constitution + six-file context system
specline new refunds # spec + plan skeletons
# ... you + your agent fill the spec ...
specline validate refunds # EARS/Gherkin/leak lint โ ambiguity dies here
specline gate spec refunds # hash-sealed human signoff
specline tasks refunds # atomicity lint: โค4 files, one slice, verify cmd
specline gate plan refunds # locks the spec hash (drift guard arms)
specline loop next refunds # emits a token-budgeted TASK PACKET
# ... agent session does exactly one packet ...
specline loop done refunds T1 # runs verify command, seals receipt, advances
specline handoff refunds # decision table -> HSF workflow spec
specline agent claude # wires CLAUDE.md + /next-task command
specline status # token-savings receipt
pytest -q # 25 tests
The mechanisms (what's actually enforced)
| Blog-post advice | SpecLine enforcement |
|---|---|
| "Write clear specs" | EARS keyword lint, Gherkin required, implementation-leak detection (E_IMPL_LEAK) |
| "Keep tasks small" | Atomicity linter: โค4 files, one vertical slice, explicit verify command, no skeleton edits |
| "Reset agent context" | The loop emits self-contained task packets under a hard ~2.2k-token budget; one packet = one session |
| "Minimize context (C_t=ฮณยทR_fยทT_d)" | Packets list the exact R_f file set; excerpt only spec lines relevant to the task; deterministic prune over budget |
| "Prevent intent drift" | Plan gate seals the spec hash; if the spec changes, the loop refuses (E_INTENT_DRIFT) until re-gated |
| "Human review gates" | `specline gate spec |
| "Don't let agents improvise business rules" | Decision tables compile through HSF: one-time generation, four gates, zero tokens per decision |
| "Measure the process" | SpecFactor gauge (Goldilocks 0.75โ2.5) + a context ledger: packet tokens vs naive baseline, % saved |
Agent integration
- Claude Code:
specline agent claudeโ writesCLAUDE.md(constitution + protocol) and.claude/commands/next-task.md. The whole loop is one slash command. - Codex:
specline agent codexโ appends the protocol toAGENTS.md(Codex reads it natively). - Anything else:
specline agent <name>โ portable constitution file. The protocol is plain text; any harness that can read a file can follow it.
The factory calibration (the part that saves real money)
Most business logic in AI-built apps is decision-shaped: ordered rules over
extracted facts. Letting agents re-implement those rules inline is how you get
inconsistent behavior and burned tokens. SpecLine specs carry a
## Decision logic table; specline handoff converts it to a Harness
Software Factory spec, and HSF compiles it once into deterministic, gated,
signed code โ verified end-to-end in this repo's test suite against a real
HSF install. App code flows through the line; decisions flow through the
factory; nothing is improvised twice.
Receipts culture
Every gate signoff, packet emission, and task completion writes a hash-sealed
line to context/PROGRESS.md, and the context ledger accumulates the token
economics (specline status โ the walkthrough example shows ~75% saved vs
naive full-context sessions, and the gap widens as the repo grows). Claims
trace to receipts, never to vibes. That's the whole point.
MIT licensed.
v0.2 โ Strict Input Contract & Drift Audit
The base linter checks that a spec looks right (EARS keywords present, valid task format). That's necessary but not sufficient: it lets ambiguity through, and the AI coder then invents the missing parameters โ which is drift. v0.2 closes that gap with two new stages that bracket the coder.
specline strict <feature> โ reject ambiguity before the coder runs
Treats the spec as a contract the coder must execute with zero invention. Every finding is a BLOCK with an exact line and fix. It catches the five drift sources:
- Incomplete requirements โ an EARS keyword isn't enough. Each requirement must
have a concrete outcome verb (
return/reject/store/โฆ), nothandle/support/manage.The system shall handle it appropriatelyis rejected. - Surviving placeholders โ
<trigger>,<N>,TBDcan't reach an approved spec. - Unquantified bounds โ a requirement that implies a timeout/limit/retry/size must state a number+unit.
- Untraceable acceptance โ every value in a Given/When/Then must be defined in a requirement or the data model. A Gherkin step can't introduce a fact the coder would have to invent.
- Non-deterministic decisions โ each rule's
ifreferences a declared fact and itsthenis exactly one outcome. Nomaybe/or/etc; no duplicate conditions. (else/defaultcatch-all rows are allowed.)
An approved spec that still fails strict raises S_APPROVED_BUT_AMBIGUOUS โ approval
is a lie until the blocks are resolved.
Strict is on by default in specline gate spec|plan. Pass strict=False to the
gate API only for legacy specs.
specline audit <feature> --files โฆ --slice โฆ โ catch drift after the coder runs
Compares what shipped against what the contract authorized:
A_INVENTED_PARAMโ a config value (TIMEOUT = 45) whose number the spec never authorized. The coder guessed; the audit fails the build.A_SCOPE_ESCAPEโ a file outside the task's authorized slice.A_UNAUTHORIZED_FILEโ a file not in the packet's list.A_STUB_LEFTโ aTODO/NotImplementedErrorleft behind.
Requirement-scoped packets
The packet excerpt no longer bag-of-words-matches individual lines (which could hand the agent half a requirement). It now ships whole requirement blocks and the complete acceptance scenario intact โ the agent never receives a partial rule to improvise around.
Flow
new โ write spec โ validate โ strict โ gate spec โ write plan โ tasks โ gate plan
โ loop (build) โ audit โ gate code โ handoff
Deterministic by design: same spec text โ same findings, every run. No LLM, no clock.
Failure attribution
SpecLine 0.3 reports strict-lint results per requirement and drift-audit results
per Python function. Failed units include a stable class such as
ambiguous_requirement, untyped_input, invented_param, or scope_escape,
plus the offending source phrase or code location. Existing pass/fail rules do
not change.
For machine-readable output:
specline strict my_feature --json
specline audit my_feature --files slices/my_feature/logic.py --json
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file code_factory_1_spec-0.3.0.tar.gz.
File metadata
- Download URL: code_factory_1_spec-0.3.0.tar.gz
- Upload date:
- Size: 30.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
babc673a1601e41ff873c1d96bf4f19131a1e62a6a27d7da689b100fbd3fca1f
|
|
| MD5 |
d7210284b962118db699873c5b66ea89
|
|
| BLAKE2b-256 |
ea308c9ac81ce703e7a0de7b7c2b86c26b83ffe9bf8cee052bc1b567f45ade57
|
File details
Details for the file code_factory_1_spec-0.3.0-py3-none-any.whl.
File metadata
- Download URL: code_factory_1_spec-0.3.0-py3-none-any.whl
- Upload date:
- Size: 35.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efc501a779fcec6a9a5f5ec37202206345fc4a146b25802c198c984e9ba44080
|
|
| MD5 |
013387b19434bef659988bd8946fffc3
|
|
| BLAKE2b-256 |
974c564f840db9b90672387781a34ad87e3bfbc90018d95ae2c82c73131586d8
|