code-factory-1-spec 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. code_factory_1_spec-0.3.0/LICENSE +21 -0
  2. code_factory_1_spec-0.3.0/PKG-INFO +199 -0
  3. code_factory_1_spec-0.3.0/README.md +186 -0
  4. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/PKG-INFO +199 -0
  5. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/SOURCES.txt +38 -0
  6. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/dependency_links.txt +1 -0
  7. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/entry_points.txt +2 -0
  8. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/requires.txt +4 -0
  9. code_factory_1_spec-0.3.0/code_factory_1_spec.egg-info/top_level.txt +1 -0
  10. code_factory_1_spec-0.3.0/pyproject.toml +27 -0
  11. code_factory_1_spec-0.3.0/setup.cfg +4 -0
  12. code_factory_1_spec-0.3.0/specline/__init__.py +16 -0
  13. code_factory_1_spec-0.3.0/specline/adapters.py +32 -0
  14. code_factory_1_spec-0.3.0/specline/attribution.py +60 -0
  15. code_factory_1_spec-0.3.0/specline/cli.py +136 -0
  16. code_factory_1_spec-0.3.0/specline/drift_audit.py +150 -0
  17. code_factory_1_spec-0.3.0/specline/gates.py +40 -0
  18. code_factory_1_spec-0.3.0/specline/handoff.py +44 -0
  19. code_factory_1_spec-0.3.0/specline/ledger.py +40 -0
  20. code_factory_1_spec-0.3.0/specline/loop.py +66 -0
  21. code_factory_1_spec-0.3.0/specline/packets.py +107 -0
  22. code_factory_1_spec-0.3.0/specline/paths.py +10 -0
  23. code_factory_1_spec-0.3.0/specline/plan_lint.py +38 -0
  24. code_factory_1_spec-0.3.0/specline/scaffold.py +40 -0
  25. code_factory_1_spec-0.3.0/specline/spec_lint.py +49 -0
  26. code_factory_1_spec-0.3.0/specline/specfactor.py +21 -0
  27. code_factory_1_spec-0.3.0/specline/strict_lint.py +308 -0
  28. code_factory_1_spec-0.3.0/templates/AGENTS.md +22 -0
  29. code_factory_1_spec-0.3.0/templates/PLAN_TEMPLATE.md +11 -0
  30. code_factory_1_spec-0.3.0/templates/SPEC_TEMPLATE.md +38 -0
  31. code_factory_1_spec-0.3.0/templates/context/AI_WORKFLOW_RULES.md +6 -0
  32. code_factory_1_spec-0.3.0/templates/context/ARCHITECTURE.md +12 -0
  33. code_factory_1_spec-0.3.0/templates/context/CODE_STANDARDS.md +6 -0
  34. code_factory_1_spec-0.3.0/templates/context/PROGRESS.md +7 -0
  35. code_factory_1_spec-0.3.0/templates/context/PROJECT_OVERVIEW.md +10 -0
  36. code_factory_1_spec-0.3.0/templates/context/UI_CONTEXT.md +4 -0
  37. code_factory_1_spec-0.3.0/templates/personas/reviewer.md +6 -0
  38. code_factory_1_spec-0.3.0/templates/personas/security_auditor.md +5 -0
  39. code_factory_1_spec-0.3.0/tests/test_specline.py +125 -0
  40. code_factory_1_spec-0.3.0/tests/test_strict.py +180 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 WizeMe.APP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-factory-1-spec
3
+ Version: 0.3.0
4
+ Summary: 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).
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: PyYAML>=6.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=8.0; extra == "dev"
12
+ Dynamic: license-file
13
+
14
+ # SpecLine 🏭
15
+
16
+ **A spec-driven production line for AI coding agents.** PRD → spec → plan →
17
+ atomic task packets → gated code → production, with token-lean context
18
+ hygiene enforced by tooling instead of discipline, and a compiled-decision
19
+ handoff to [Harness Software Factory](../harness-factory) for the logic that
20
+ should never be improvised twice.
21
+
22
+ Works with **Claude Code, Codex, and any agent harness** — one command wires it in.
23
+
24
+ ## Workflow at a glance
25
+
26
+ ```mermaid
27
+ flowchart LR
28
+ A["PRD or rough idea"] --> B["Draft spec"]
29
+ B --> C["Strict contract check"]
30
+ C -->|"blocks ambiguity"| B
31
+ C --> D["Gate spec and seal hash"]
32
+ D --> E["Create atomic plan"]
33
+ E --> F["Emit one task packet"]
34
+ F --> G["Agent builds exactly one slice"]
35
+ G --> H["Audit code against packet"]
36
+ H -->|"drift found"| F
37
+ H --> I["Gate code and update receipts"]
38
+ I --> J{"Decision table?"}
39
+ J -->|"yes"| K["Handoff to HSF"]
40
+ J -->|"no"| L["Ready for ForgeLine or PR"]
41
+ ```
42
+
43
+ ```
44
+ PRD ──> Spec (EARS+Gherkin) ──> Gate ──> Plan (atomic tasks) ──> Gate
45
+
46
+ ┌─────────────────────────────────────────┘
47
+
48
+ ┌── Ralph Wiggum Loop ──┐ Decision tables in the spec
49
+ │ specline loop next │ ──> specline handoff
50
+ │ → token-budgeted │ ──> HSF compiles them ONCE into
51
+ │ TASK PACKET │ gated, deterministic code
52
+ │ agent does ONE task │ (zero tokens per decision, forever)
53
+ │ specline loop done │
54
+ │ → verify + seal │
55
+ └──── context reset ────┘ ──> Gate ──> ship
56
+ ```
57
+
58
+ ## Why
59
+
60
+ Vibe coding hits the wall around four files: context pollution, intent
61
+ drift, API hallucinations. The fixes are known — specs as source of truth,
62
+ constitutions, vertical slices, context resets — but they live in blog
63
+ posts as *discipline*. SpecLine turns them into *tooling*: linted, gated,
64
+ hash-sealed, and receipt-audited, so the discipline holds at 2am too.
65
+
66
+ ## Quickstart (5 minutes, no API keys)
67
+
68
+ ```bash
69
+ pip install -e ".[dev]"
70
+ specline init # constitution + six-file context system
71
+ specline new refunds # spec + plan skeletons
72
+ # ... you + your agent fill the spec ...
73
+ specline validate refunds # EARS/Gherkin/leak lint — ambiguity dies here
74
+ specline gate spec refunds # hash-sealed human signoff
75
+ specline tasks refunds # atomicity lint: ≤4 files, one slice, verify cmd
76
+ specline gate plan refunds # locks the spec hash (drift guard arms)
77
+ specline loop next refunds # emits a token-budgeted TASK PACKET
78
+ # ... agent session does exactly one packet ...
79
+ specline loop done refunds T1 # runs verify command, seals receipt, advances
80
+ specline handoff refunds # decision table -> HSF workflow spec
81
+ specline agent claude # wires CLAUDE.md + /next-task command
82
+ specline status # token-savings receipt
83
+ pytest -q # 25 tests
84
+ ```
85
+
86
+ ## The mechanisms (what's actually enforced)
87
+
88
+ | Blog-post advice | SpecLine enforcement |
89
+ |---|---|
90
+ | "Write clear specs" | EARS keyword lint, Gherkin required, implementation-leak detection (`E_IMPL_LEAK`) |
91
+ | "Keep tasks small" | Atomicity linter: ≤4 files, one vertical slice, explicit verify command, no skeleton edits |
92
+ | "Reset agent context" | The loop emits self-contained **task packets** under a hard ~2.2k-token budget; one packet = one session |
93
+ | "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 |
94
+ | "Prevent intent drift" | Plan gate seals the spec hash; if the spec changes, the loop **refuses** (`E_INTENT_DRIFT`) until re-gated |
95
+ | "Human review gates" | `specline gate spec|plan|code` writes hash-sealed signoff receipts to the progress tracker |
96
+ | "Don't let agents improvise business rules" | Decision tables compile through HSF: one-time generation, four gates, zero tokens per decision |
97
+ | "Measure the process" | SpecFactor gauge (Goldilocks 0.75–2.5) + a **context ledger**: packet tokens vs naive baseline, % saved |
98
+
99
+ ## Agent integration
100
+
101
+ - **Claude Code:** `specline agent claude` → writes `CLAUDE.md` (constitution +
102
+ protocol) and `.claude/commands/next-task.md`. The whole loop is one slash command.
103
+ - **Codex:** `specline agent codex` → appends the protocol to `AGENTS.md`
104
+ (Codex reads it natively).
105
+ - **Anything else:** `specline agent <name>` → portable constitution file.
106
+ The protocol is plain text; any harness that can read a file can follow it.
107
+
108
+ ## The factory calibration (the part that saves real money)
109
+
110
+ Most business logic in AI-built apps is *decision-shaped*: ordered rules over
111
+ extracted facts. Letting agents re-implement those rules inline is how you get
112
+ inconsistent behavior and burned tokens. SpecLine specs carry a
113
+ `## Decision logic` table; `specline handoff` converts it to a Harness
114
+ Software Factory spec, and HSF compiles it once into deterministic, gated,
115
+ signed code — verified end-to-end in this repo's test suite against a real
116
+ HSF install. App code flows through the line; decisions flow through the
117
+ factory; nothing is improvised twice.
118
+
119
+ ## Receipts culture
120
+
121
+ Every gate signoff, packet emission, and task completion writes a hash-sealed
122
+ line to `context/PROGRESS.md`, and the context ledger accumulates the token
123
+ economics (`specline status` — the walkthrough example shows ~75% saved vs
124
+ naive full-context sessions, and the gap widens as the repo grows). Claims
125
+ trace to receipts, never to vibes. That's the whole point.
126
+
127
+ MIT licensed.
128
+
129
+ ---
130
+
131
+ ## v0.2 — Strict Input Contract & Drift Audit
132
+
133
+ The base linter checks that a spec *looks* right (EARS keywords present, valid task
134
+ format). That's necessary but not sufficient: it lets **ambiguity** through, and the
135
+ AI coder then *invents* the missing parameters — which is drift. v0.2 closes that gap
136
+ with two new stages that bracket the coder.
137
+
138
+ ### `specline strict <feature>` — reject ambiguity *before* the coder runs
139
+
140
+ Treats the spec as a **contract the coder must execute with zero invention**. Every
141
+ finding is a BLOCK with an exact line and fix. It catches the five drift sources:
142
+
143
+ 1. **Incomplete requirements** — an EARS keyword isn't enough. Each requirement must
144
+ have a concrete outcome verb (`return`/`reject`/`store`/…), not `handle`/`support`/
145
+ `manage`. `The system shall handle it appropriately` is rejected.
146
+ 2. **Surviving placeholders** — `<trigger>`, `<N>`, `TBD` can't reach an approved spec.
147
+ 3. **Unquantified bounds** — a requirement that implies a timeout/limit/retry/size must
148
+ state a number+unit.
149
+ 4. **Untraceable acceptance** — every value in a Given/When/Then must be defined in a
150
+ requirement or the data model. A Gherkin step can't introduce a fact the coder would
151
+ have to invent.
152
+ 5. **Non-deterministic decisions** — each rule's `if` references a declared fact and its
153
+ `then` is exactly one outcome. No `maybe`/`or`/`etc`; no duplicate conditions.
154
+ (`else`/`default` catch-all rows are allowed.)
155
+
156
+ An `approved` spec that still fails strict raises `S_APPROVED_BUT_AMBIGUOUS` — approval
157
+ is a lie until the blocks are resolved.
158
+
159
+ Strict is **on by default** in `specline gate spec|plan`. Pass `strict=False` to the
160
+ gate API only for legacy specs.
161
+
162
+ ### `specline audit <feature> --files … --slice …` — catch drift *after* the coder runs
163
+
164
+ Compares what shipped against what the contract authorized:
165
+
166
+ - **`A_INVENTED_PARAM`** — a config value (`TIMEOUT = 45`) whose number the spec never
167
+ authorized. The coder guessed; the audit fails the build.
168
+ - **`A_SCOPE_ESCAPE`** — a file outside the task's authorized slice.
169
+ - **`A_UNAUTHORIZED_FILE`** — a file not in the packet's list.
170
+ - **`A_STUB_LEFT`** — a `TODO`/`NotImplementedError` left behind.
171
+
172
+ ### Requirement-scoped packets
173
+
174
+ The packet excerpt no longer bag-of-words-matches individual lines (which could hand the
175
+ agent half a requirement). It now ships **whole requirement blocks** and the **complete
176
+ acceptance scenario intact** — the agent never receives a partial rule to improvise around.
177
+
178
+ ### Flow
179
+
180
+ ```
181
+ new → write spec → validate → strict → gate spec → write plan → tasks → gate plan
182
+ → loop (build) → audit → gate code → handoff
183
+ ```
184
+
185
+ Deterministic by design: same spec text → same findings, every run. No LLM, no clock.
186
+ ## Failure attribution
187
+
188
+ SpecLine 0.3 reports strict-lint results per requirement and drift-audit results
189
+ per Python function. Failed units include a stable class such as
190
+ `ambiguous_requirement`, `untyped_input`, `invented_param`, or `scope_escape`,
191
+ plus the offending source phrase or code location. Existing pass/fail rules do
192
+ not change.
193
+
194
+ For machine-readable output:
195
+
196
+ ```bash
197
+ specline strict my_feature --json
198
+ specline audit my_feature --files slices/my_feature/logic.py --json
199
+ ```
@@ -0,0 +1,186 @@
1
+ # SpecLine 🏭
2
+
3
+ **A spec-driven production line for AI coding agents.** PRD → spec → plan →
4
+ atomic task packets → gated code → production, with token-lean context
5
+ hygiene enforced by tooling instead of discipline, and a compiled-decision
6
+ handoff to [Harness Software Factory](../harness-factory) for the logic that
7
+ should never be improvised twice.
8
+
9
+ Works with **Claude Code, Codex, and any agent harness** — one command wires it in.
10
+
11
+ ## Workflow at a glance
12
+
13
+ ```mermaid
14
+ flowchart LR
15
+ A["PRD or rough idea"] --> B["Draft spec"]
16
+ B --> C["Strict contract check"]
17
+ C -->|"blocks ambiguity"| B
18
+ C --> D["Gate spec and seal hash"]
19
+ D --> E["Create atomic plan"]
20
+ E --> F["Emit one task packet"]
21
+ F --> G["Agent builds exactly one slice"]
22
+ G --> H["Audit code against packet"]
23
+ H -->|"drift found"| F
24
+ H --> I["Gate code and update receipts"]
25
+ I --> J{"Decision table?"}
26
+ J -->|"yes"| K["Handoff to HSF"]
27
+ J -->|"no"| L["Ready for ForgeLine or PR"]
28
+ ```
29
+
30
+ ```
31
+ PRD ──> Spec (EARS+Gherkin) ──> Gate ──> Plan (atomic tasks) ──> Gate
32
+
33
+ ┌─────────────────────────────────────────┘
34
+
35
+ ┌── Ralph Wiggum Loop ──┐ Decision tables in the spec
36
+ │ specline loop next │ ──> specline handoff
37
+ │ → token-budgeted │ ──> HSF compiles them ONCE into
38
+ │ TASK PACKET │ gated, deterministic code
39
+ │ agent does ONE task │ (zero tokens per decision, forever)
40
+ │ specline loop done │
41
+ │ → verify + seal │
42
+ └──── context reset ────┘ ──> Gate ──> ship
43
+ ```
44
+
45
+ ## Why
46
+
47
+ Vibe coding hits the wall around four files: context pollution, intent
48
+ drift, API hallucinations. The fixes are known — specs as source of truth,
49
+ constitutions, vertical slices, context resets — but they live in blog
50
+ posts as *discipline*. SpecLine turns them into *tooling*: linted, gated,
51
+ hash-sealed, and receipt-audited, so the discipline holds at 2am too.
52
+
53
+ ## Quickstart (5 minutes, no API keys)
54
+
55
+ ```bash
56
+ pip install -e ".[dev]"
57
+ specline init # constitution + six-file context system
58
+ specline new refunds # spec + plan skeletons
59
+ # ... you + your agent fill the spec ...
60
+ specline validate refunds # EARS/Gherkin/leak lint — ambiguity dies here
61
+ specline gate spec refunds # hash-sealed human signoff
62
+ specline tasks refunds # atomicity lint: ≤4 files, one slice, verify cmd
63
+ specline gate plan refunds # locks the spec hash (drift guard arms)
64
+ specline loop next refunds # emits a token-budgeted TASK PACKET
65
+ # ... agent session does exactly one packet ...
66
+ specline loop done refunds T1 # runs verify command, seals receipt, advances
67
+ specline handoff refunds # decision table -> HSF workflow spec
68
+ specline agent claude # wires CLAUDE.md + /next-task command
69
+ specline status # token-savings receipt
70
+ pytest -q # 25 tests
71
+ ```
72
+
73
+ ## The mechanisms (what's actually enforced)
74
+
75
+ | Blog-post advice | SpecLine enforcement |
76
+ |---|---|
77
+ | "Write clear specs" | EARS keyword lint, Gherkin required, implementation-leak detection (`E_IMPL_LEAK`) |
78
+ | "Keep tasks small" | Atomicity linter: ≤4 files, one vertical slice, explicit verify command, no skeleton edits |
79
+ | "Reset agent context" | The loop emits self-contained **task packets** under a hard ~2.2k-token budget; one packet = one session |
80
+ | "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 |
81
+ | "Prevent intent drift" | Plan gate seals the spec hash; if the spec changes, the loop **refuses** (`E_INTENT_DRIFT`) until re-gated |
82
+ | "Human review gates" | `specline gate spec|plan|code` writes hash-sealed signoff receipts to the progress tracker |
83
+ | "Don't let agents improvise business rules" | Decision tables compile through HSF: one-time generation, four gates, zero tokens per decision |
84
+ | "Measure the process" | SpecFactor gauge (Goldilocks 0.75–2.5) + a **context ledger**: packet tokens vs naive baseline, % saved |
85
+
86
+ ## Agent integration
87
+
88
+ - **Claude Code:** `specline agent claude` → writes `CLAUDE.md` (constitution +
89
+ protocol) and `.claude/commands/next-task.md`. The whole loop is one slash command.
90
+ - **Codex:** `specline agent codex` → appends the protocol to `AGENTS.md`
91
+ (Codex reads it natively).
92
+ - **Anything else:** `specline agent <name>` → portable constitution file.
93
+ The protocol is plain text; any harness that can read a file can follow it.
94
+
95
+ ## The factory calibration (the part that saves real money)
96
+
97
+ Most business logic in AI-built apps is *decision-shaped*: ordered rules over
98
+ extracted facts. Letting agents re-implement those rules inline is how you get
99
+ inconsistent behavior and burned tokens. SpecLine specs carry a
100
+ `## Decision logic` table; `specline handoff` converts it to a Harness
101
+ Software Factory spec, and HSF compiles it once into deterministic, gated,
102
+ signed code — verified end-to-end in this repo's test suite against a real
103
+ HSF install. App code flows through the line; decisions flow through the
104
+ factory; nothing is improvised twice.
105
+
106
+ ## Receipts culture
107
+
108
+ Every gate signoff, packet emission, and task completion writes a hash-sealed
109
+ line to `context/PROGRESS.md`, and the context ledger accumulates the token
110
+ economics (`specline status` — the walkthrough example shows ~75% saved vs
111
+ naive full-context sessions, and the gap widens as the repo grows). Claims
112
+ trace to receipts, never to vibes. That's the whole point.
113
+
114
+ MIT licensed.
115
+
116
+ ---
117
+
118
+ ## v0.2 — Strict Input Contract & Drift Audit
119
+
120
+ The base linter checks that a spec *looks* right (EARS keywords present, valid task
121
+ format). That's necessary but not sufficient: it lets **ambiguity** through, and the
122
+ AI coder then *invents* the missing parameters — which is drift. v0.2 closes that gap
123
+ with two new stages that bracket the coder.
124
+
125
+ ### `specline strict <feature>` — reject ambiguity *before* the coder runs
126
+
127
+ Treats the spec as a **contract the coder must execute with zero invention**. Every
128
+ finding is a BLOCK with an exact line and fix. It catches the five drift sources:
129
+
130
+ 1. **Incomplete requirements** — an EARS keyword isn't enough. Each requirement must
131
+ have a concrete outcome verb (`return`/`reject`/`store`/…), not `handle`/`support`/
132
+ `manage`. `The system shall handle it appropriately` is rejected.
133
+ 2. **Surviving placeholders** — `<trigger>`, `<N>`, `TBD` can't reach an approved spec.
134
+ 3. **Unquantified bounds** — a requirement that implies a timeout/limit/retry/size must
135
+ state a number+unit.
136
+ 4. **Untraceable acceptance** — every value in a Given/When/Then must be defined in a
137
+ requirement or the data model. A Gherkin step can't introduce a fact the coder would
138
+ have to invent.
139
+ 5. **Non-deterministic decisions** — each rule's `if` references a declared fact and its
140
+ `then` is exactly one outcome. No `maybe`/`or`/`etc`; no duplicate conditions.
141
+ (`else`/`default` catch-all rows are allowed.)
142
+
143
+ An `approved` spec that still fails strict raises `S_APPROVED_BUT_AMBIGUOUS` — approval
144
+ is a lie until the blocks are resolved.
145
+
146
+ Strict is **on by default** in `specline gate spec|plan`. Pass `strict=False` to the
147
+ gate API only for legacy specs.
148
+
149
+ ### `specline audit <feature> --files … --slice …` — catch drift *after* the coder runs
150
+
151
+ Compares what shipped against what the contract authorized:
152
+
153
+ - **`A_INVENTED_PARAM`** — a config value (`TIMEOUT = 45`) whose number the spec never
154
+ authorized. The coder guessed; the audit fails the build.
155
+ - **`A_SCOPE_ESCAPE`** — a file outside the task's authorized slice.
156
+ - **`A_UNAUTHORIZED_FILE`** — a file not in the packet's list.
157
+ - **`A_STUB_LEFT`** — a `TODO`/`NotImplementedError` left behind.
158
+
159
+ ### Requirement-scoped packets
160
+
161
+ The packet excerpt no longer bag-of-words-matches individual lines (which could hand the
162
+ agent half a requirement). It now ships **whole requirement blocks** and the **complete
163
+ acceptance scenario intact** — the agent never receives a partial rule to improvise around.
164
+
165
+ ### Flow
166
+
167
+ ```
168
+ new → write spec → validate → strict → gate spec → write plan → tasks → gate plan
169
+ → loop (build) → audit → gate code → handoff
170
+ ```
171
+
172
+ Deterministic by design: same spec text → same findings, every run. No LLM, no clock.
173
+ ## Failure attribution
174
+
175
+ SpecLine 0.3 reports strict-lint results per requirement and drift-audit results
176
+ per Python function. Failed units include a stable class such as
177
+ `ambiguous_requirement`, `untyped_input`, `invented_param`, or `scope_escape`,
178
+ plus the offending source phrase or code location. Existing pass/fail rules do
179
+ not change.
180
+
181
+ For machine-readable output:
182
+
183
+ ```bash
184
+ specline strict my_feature --json
185
+ specline audit my_feature --files slices/my_feature/logic.py --json
186
+ ```
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-factory-1-spec
3
+ Version: 0.3.0
4
+ Summary: 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).
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: PyYAML>=6.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=8.0; extra == "dev"
12
+ Dynamic: license-file
13
+
14
+ # SpecLine 🏭
15
+
16
+ **A spec-driven production line for AI coding agents.** PRD → spec → plan →
17
+ atomic task packets → gated code → production, with token-lean context
18
+ hygiene enforced by tooling instead of discipline, and a compiled-decision
19
+ handoff to [Harness Software Factory](../harness-factory) for the logic that
20
+ should never be improvised twice.
21
+
22
+ Works with **Claude Code, Codex, and any agent harness** — one command wires it in.
23
+
24
+ ## Workflow at a glance
25
+
26
+ ```mermaid
27
+ flowchart LR
28
+ A["PRD or rough idea"] --> B["Draft spec"]
29
+ B --> C["Strict contract check"]
30
+ C -->|"blocks ambiguity"| B
31
+ C --> D["Gate spec and seal hash"]
32
+ D --> E["Create atomic plan"]
33
+ E --> F["Emit one task packet"]
34
+ F --> G["Agent builds exactly one slice"]
35
+ G --> H["Audit code against packet"]
36
+ H -->|"drift found"| F
37
+ H --> I["Gate code and update receipts"]
38
+ I --> J{"Decision table?"}
39
+ J -->|"yes"| K["Handoff to HSF"]
40
+ J -->|"no"| L["Ready for ForgeLine or PR"]
41
+ ```
42
+
43
+ ```
44
+ PRD ──> Spec (EARS+Gherkin) ──> Gate ──> Plan (atomic tasks) ──> Gate
45
+
46
+ ┌─────────────────────────────────────────┘
47
+
48
+ ┌── Ralph Wiggum Loop ──┐ Decision tables in the spec
49
+ │ specline loop next │ ──> specline handoff
50
+ │ → token-budgeted │ ──> HSF compiles them ONCE into
51
+ │ TASK PACKET │ gated, deterministic code
52
+ │ agent does ONE task │ (zero tokens per decision, forever)
53
+ │ specline loop done │
54
+ │ → verify + seal │
55
+ └──── context reset ────┘ ──> Gate ──> ship
56
+ ```
57
+
58
+ ## Why
59
+
60
+ Vibe coding hits the wall around four files: context pollution, intent
61
+ drift, API hallucinations. The fixes are known — specs as source of truth,
62
+ constitutions, vertical slices, context resets — but they live in blog
63
+ posts as *discipline*. SpecLine turns them into *tooling*: linted, gated,
64
+ hash-sealed, and receipt-audited, so the discipline holds at 2am too.
65
+
66
+ ## Quickstart (5 minutes, no API keys)
67
+
68
+ ```bash
69
+ pip install -e ".[dev]"
70
+ specline init # constitution + six-file context system
71
+ specline new refunds # spec + plan skeletons
72
+ # ... you + your agent fill the spec ...
73
+ specline validate refunds # EARS/Gherkin/leak lint — ambiguity dies here
74
+ specline gate spec refunds # hash-sealed human signoff
75
+ specline tasks refunds # atomicity lint: ≤4 files, one slice, verify cmd
76
+ specline gate plan refunds # locks the spec hash (drift guard arms)
77
+ specline loop next refunds # emits a token-budgeted TASK PACKET
78
+ # ... agent session does exactly one packet ...
79
+ specline loop done refunds T1 # runs verify command, seals receipt, advances
80
+ specline handoff refunds # decision table -> HSF workflow spec
81
+ specline agent claude # wires CLAUDE.md + /next-task command
82
+ specline status # token-savings receipt
83
+ pytest -q # 25 tests
84
+ ```
85
+
86
+ ## The mechanisms (what's actually enforced)
87
+
88
+ | Blog-post advice | SpecLine enforcement |
89
+ |---|---|
90
+ | "Write clear specs" | EARS keyword lint, Gherkin required, implementation-leak detection (`E_IMPL_LEAK`) |
91
+ | "Keep tasks small" | Atomicity linter: ≤4 files, one vertical slice, explicit verify command, no skeleton edits |
92
+ | "Reset agent context" | The loop emits self-contained **task packets** under a hard ~2.2k-token budget; one packet = one session |
93
+ | "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 |
94
+ | "Prevent intent drift" | Plan gate seals the spec hash; if the spec changes, the loop **refuses** (`E_INTENT_DRIFT`) until re-gated |
95
+ | "Human review gates" | `specline gate spec|plan|code` writes hash-sealed signoff receipts to the progress tracker |
96
+ | "Don't let agents improvise business rules" | Decision tables compile through HSF: one-time generation, four gates, zero tokens per decision |
97
+ | "Measure the process" | SpecFactor gauge (Goldilocks 0.75–2.5) + a **context ledger**: packet tokens vs naive baseline, % saved |
98
+
99
+ ## Agent integration
100
+
101
+ - **Claude Code:** `specline agent claude` → writes `CLAUDE.md` (constitution +
102
+ protocol) and `.claude/commands/next-task.md`. The whole loop is one slash command.
103
+ - **Codex:** `specline agent codex` → appends the protocol to `AGENTS.md`
104
+ (Codex reads it natively).
105
+ - **Anything else:** `specline agent <name>` → portable constitution file.
106
+ The protocol is plain text; any harness that can read a file can follow it.
107
+
108
+ ## The factory calibration (the part that saves real money)
109
+
110
+ Most business logic in AI-built apps is *decision-shaped*: ordered rules over
111
+ extracted facts. Letting agents re-implement those rules inline is how you get
112
+ inconsistent behavior and burned tokens. SpecLine specs carry a
113
+ `## Decision logic` table; `specline handoff` converts it to a Harness
114
+ Software Factory spec, and HSF compiles it once into deterministic, gated,
115
+ signed code — verified end-to-end in this repo's test suite against a real
116
+ HSF install. App code flows through the line; decisions flow through the
117
+ factory; nothing is improvised twice.
118
+
119
+ ## Receipts culture
120
+
121
+ Every gate signoff, packet emission, and task completion writes a hash-sealed
122
+ line to `context/PROGRESS.md`, and the context ledger accumulates the token
123
+ economics (`specline status` — the walkthrough example shows ~75% saved vs
124
+ naive full-context sessions, and the gap widens as the repo grows). Claims
125
+ trace to receipts, never to vibes. That's the whole point.
126
+
127
+ MIT licensed.
128
+
129
+ ---
130
+
131
+ ## v0.2 — Strict Input Contract & Drift Audit
132
+
133
+ The base linter checks that a spec *looks* right (EARS keywords present, valid task
134
+ format). That's necessary but not sufficient: it lets **ambiguity** through, and the
135
+ AI coder then *invents* the missing parameters — which is drift. v0.2 closes that gap
136
+ with two new stages that bracket the coder.
137
+
138
+ ### `specline strict <feature>` — reject ambiguity *before* the coder runs
139
+
140
+ Treats the spec as a **contract the coder must execute with zero invention**. Every
141
+ finding is a BLOCK with an exact line and fix. It catches the five drift sources:
142
+
143
+ 1. **Incomplete requirements** — an EARS keyword isn't enough. Each requirement must
144
+ have a concrete outcome verb (`return`/`reject`/`store`/…), not `handle`/`support`/
145
+ `manage`. `The system shall handle it appropriately` is rejected.
146
+ 2. **Surviving placeholders** — `<trigger>`, `<N>`, `TBD` can't reach an approved spec.
147
+ 3. **Unquantified bounds** — a requirement that implies a timeout/limit/retry/size must
148
+ state a number+unit.
149
+ 4. **Untraceable acceptance** — every value in a Given/When/Then must be defined in a
150
+ requirement or the data model. A Gherkin step can't introduce a fact the coder would
151
+ have to invent.
152
+ 5. **Non-deterministic decisions** — each rule's `if` references a declared fact and its
153
+ `then` is exactly one outcome. No `maybe`/`or`/`etc`; no duplicate conditions.
154
+ (`else`/`default` catch-all rows are allowed.)
155
+
156
+ An `approved` spec that still fails strict raises `S_APPROVED_BUT_AMBIGUOUS` — approval
157
+ is a lie until the blocks are resolved.
158
+
159
+ Strict is **on by default** in `specline gate spec|plan`. Pass `strict=False` to the
160
+ gate API only for legacy specs.
161
+
162
+ ### `specline audit <feature> --files … --slice …` — catch drift *after* the coder runs
163
+
164
+ Compares what shipped against what the contract authorized:
165
+
166
+ - **`A_INVENTED_PARAM`** — a config value (`TIMEOUT = 45`) whose number the spec never
167
+ authorized. The coder guessed; the audit fails the build.
168
+ - **`A_SCOPE_ESCAPE`** — a file outside the task's authorized slice.
169
+ - **`A_UNAUTHORIZED_FILE`** — a file not in the packet's list.
170
+ - **`A_STUB_LEFT`** — a `TODO`/`NotImplementedError` left behind.
171
+
172
+ ### Requirement-scoped packets
173
+
174
+ The packet excerpt no longer bag-of-words-matches individual lines (which could hand the
175
+ agent half a requirement). It now ships **whole requirement blocks** and the **complete
176
+ acceptance scenario intact** — the agent never receives a partial rule to improvise around.
177
+
178
+ ### Flow
179
+
180
+ ```
181
+ new → write spec → validate → strict → gate spec → write plan → tasks → gate plan
182
+ → loop (build) → audit → gate code → handoff
183
+ ```
184
+
185
+ Deterministic by design: same spec text → same findings, every run. No LLM, no clock.
186
+ ## Failure attribution
187
+
188
+ SpecLine 0.3 reports strict-lint results per requirement and drift-audit results
189
+ per Python function. Failed units include a stable class such as
190
+ `ambiguous_requirement`, `untyped_input`, `invented_param`, or `scope_escape`,
191
+ plus the offending source phrase or code location. Existing pass/fail rules do
192
+ not change.
193
+
194
+ For machine-readable output:
195
+
196
+ ```bash
197
+ specline strict my_feature --json
198
+ specline audit my_feature --files slices/my_feature/logic.py --json
199
+ ```
@@ -0,0 +1,38 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ code_factory_1_spec.egg-info/PKG-INFO
5
+ code_factory_1_spec.egg-info/SOURCES.txt
6
+ code_factory_1_spec.egg-info/dependency_links.txt
7
+ code_factory_1_spec.egg-info/entry_points.txt
8
+ code_factory_1_spec.egg-info/requires.txt
9
+ code_factory_1_spec.egg-info/top_level.txt
10
+ specline/__init__.py
11
+ specline/adapters.py
12
+ specline/attribution.py
13
+ specline/cli.py
14
+ specline/drift_audit.py
15
+ specline/gates.py
16
+ specline/handoff.py
17
+ specline/ledger.py
18
+ specline/loop.py
19
+ specline/packets.py
20
+ specline/paths.py
21
+ specline/plan_lint.py
22
+ specline/scaffold.py
23
+ specline/spec_lint.py
24
+ specline/specfactor.py
25
+ specline/strict_lint.py
26
+ specline/../templates/AGENTS.md
27
+ specline/../templates/PLAN_TEMPLATE.md
28
+ specline/../templates/SPEC_TEMPLATE.md
29
+ specline/../templates/context/AI_WORKFLOW_RULES.md
30
+ specline/../templates/context/ARCHITECTURE.md
31
+ specline/../templates/context/CODE_STANDARDS.md
32
+ specline/../templates/context/PROGRESS.md
33
+ specline/../templates/context/PROJECT_OVERVIEW.md
34
+ specline/../templates/context/UI_CONTEXT.md
35
+ specline/../templates/personas/reviewer.md
36
+ specline/../templates/personas/security_auditor.md
37
+ tests/test_specline.py
38
+ tests/test_strict.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ specline = specline.cli:main
@@ -0,0 +1,4 @@
1
+ PyYAML>=6.0
2
+
3
+ [dev]
4
+ pytest>=8.0