pi-aia-asf 0.2.0 → 0.2.2
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.
- package/CHANGELOG.md +30 -0
- package/index.ts +17 -9
- package/package.json +1 -1
- package/skills/aia-asf/SKILL.md +66 -25
- package/skills/aia-asf/references/01-intake.md +6 -0
- package/skills/aia-asf/references/04-adversarial.md +10 -0
- package/skills/aia-asf/references/05-plan.md +8 -2
- package/skills/aia-asf/references/06-implementation.md +6 -0
- package/skills/aia-asf/references/06c-code-quality.md +170 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2026-08-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Mandatory modularity & maintainability standard** (`references/06c-code-quality.md`) — 8 rules distilled from Bruno's Tunnel-project philosophy (small well-readable modules plugged in where needed; one authoritative implementation for shared functionality with a single escalation path; no hardcoding — config-driven; fully testable outside the host then integrated verbatim, same modules in tests and production; refactor what is too complex to understand; layered with clear one-way boundaries and an architecture writeup; full I/O debug logging with replay of stored data; nothing may break existing functionality) and reinforced by external research (SSOT, testability as design property, ports-and-adapters seams).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Phase 6** now requires reading `06c-code-quality.md` before structuring code; **Phase 7** verification includes the modularity DoD (no duplicated shared logic, no hardcoded config values, standalone-tested modules, architecture writeup, existing functionality green).
|
|
19
|
+
- **Phase 4** adversarial analysis gains a code-quality lens (duplication, single escalation path, standalone testability, hardcoded values); **Phase 5** PLAN.md architecture section now requires the SSOT map, layering rules, and standalone-testability notes.
|
|
20
|
+
- Anti-patterns extended: god-objects, copy-pasted shared logic, test copies of modules, hardcoding, per-caller escalation logic, untestable-standalone modules, behavior-breaking refactors.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## [0.2.1] - 2026-08-14
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **Scale-based flow.** Every ASF activation is now classified **small** or **large**:
|
|
28
|
+
- **Small** (small features, minor bugfixes, small refactors) — runs **automatically**: no intake question barrage (at most one clarifying question), no research, no adversarial gate, no PLAN.md, no approval. State the intent, capture specs silently, implement test-first, verify, deliver.
|
|
29
|
+
- **Large** (new projects, significant features, major bugfixes, architectural refactors) — full gated flow unchanged: intake → research → specs → adversarial → PLAN.md → **explicit approval** → implementation → verification.
|
|
30
|
+
- When in doubt, **default to small and start working**; re-classify upward if the work grows.
|
|
31
|
+
- **`/asf small`** command — starts a small session directly in implementation phase. `/asf status` now shows the scale (`automatic — no gates` for small).
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- All gates (1–5) explicitly apply to large work only; Phase 2 (research) and Phase 5 (PLAN.md + approval) are skipped entirely for small work.
|
|
36
|
+
- References `01-intake`, `04-adversarial`, `05-plan` annotated with the scale rule.
|
|
37
|
+
- Anti-patterns: no question barrage or PLAN.md/approval demand for small work; when in doubt, start small.
|
|
38
|
+
|
|
39
|
+
|
|
10
40
|
## [0.2.0] - 2026-08-14
|
|
11
41
|
|
|
12
42
|
### Added
|
package/index.ts
CHANGED
|
@@ -30,8 +30,11 @@ type AsfPhase =
|
|
|
30
30
|
| "implementation"
|
|
31
31
|
| "verification";
|
|
32
32
|
|
|
33
|
+
type AsfScale = "small" | "large";
|
|
34
|
+
|
|
33
35
|
interface AsfState {
|
|
34
36
|
workType?: "new-project" | "feature" | "major-bugfix" | "refactor";
|
|
37
|
+
scale?: AsfScale;
|
|
35
38
|
phase: AsfPhase;
|
|
36
39
|
planApproved?: boolean;
|
|
37
40
|
startedAt?: string;
|
|
@@ -160,7 +163,7 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
160
163
|
// Startup check: warn once per session if deps are missing (unless disabled)
|
|
161
164
|
// The extension loads at startup; log to console so it surfaces in logs.
|
|
162
165
|
|
|
163
|
-
const setPhase = async (ctx: ExtensionCommandContext, phase: AsfPhase, workType?: AsfState["workType"]): Promise<string> => {
|
|
166
|
+
const setPhase = async (ctx: ExtensionCommandContext, phase: AsfPhase, workType?: AsfState["workType"], scale?: AsfScale): Promise<string> => {
|
|
164
167
|
const project = projectName();
|
|
165
168
|
const state = await loadState(project);
|
|
166
169
|
const now = new Date().toISOString();
|
|
@@ -183,6 +186,7 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
183
186
|
};
|
|
184
187
|
}
|
|
185
188
|
if (workType) state.current.workType = workType;
|
|
189
|
+
if (scale) state.current.scale = scale;
|
|
186
190
|
state.current.phase = phase;
|
|
187
191
|
state.current.updatedAt = now;
|
|
188
192
|
}
|
|
@@ -196,13 +200,15 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
196
200
|
|
|
197
201
|
switch (sub) {
|
|
198
202
|
case "new":
|
|
199
|
-
return await setPhase(ctx, "intake", "new-project");
|
|
203
|
+
return await setPhase(ctx, "intake", "new-project", "large");
|
|
200
204
|
case "feature":
|
|
201
|
-
return await setPhase(ctx, "intake", "feature");
|
|
205
|
+
return await setPhase(ctx, "intake", "feature", "large");
|
|
202
206
|
case "bugfix":
|
|
203
|
-
return await setPhase(ctx, "intake", "major-bugfix");
|
|
207
|
+
return await setPhase(ctx, "intake", "major-bugfix", "large");
|
|
204
208
|
case "refactor":
|
|
205
|
-
return await setPhase(ctx, "intake", "refactor");
|
|
209
|
+
return await setPhase(ctx, "intake", "refactor", "large");
|
|
210
|
+
case "small":
|
|
211
|
+
return await setPhase(ctx, "implementation", undefined, "small");
|
|
206
212
|
case "status": {
|
|
207
213
|
const project = projectName();
|
|
208
214
|
const state = await loadState(project);
|
|
@@ -210,6 +216,7 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
210
216
|
return (
|
|
211
217
|
`ASF status (${project}):\n` +
|
|
212
218
|
` work type: ${state.current.workType || "unset"}\n` +
|
|
219
|
+
` scale: ${state.current.scale || "unset"}${state.current.scale === "small" ? " (automatic — no gates)" : ""}\n` +
|
|
213
220
|
` phase: ${state.current.phase}\n` +
|
|
214
221
|
` plan approved: ${state.current.planApproved ? "yes" : "no"}\n` +
|
|
215
222
|
` started: ${state.current.startedAt || "?"}\n` +
|
|
@@ -236,10 +243,11 @@ export default function register(pi: ExtensionAPI): void {
|
|
|
236
243
|
default:
|
|
237
244
|
return (
|
|
238
245
|
"ASF commands:\n" +
|
|
239
|
-
" /asf new — start a new software project\n" +
|
|
240
|
-
" /asf feature — add a feature to an existing project\n" +
|
|
241
|
-
" /asf bugfix — major bugfix\n" +
|
|
242
|
-
" /asf refactor — architectural refactor\n" +
|
|
246
|
+
" /asf new — start a new software project (large, gated)\n" +
|
|
247
|
+
" /asf feature — add a feature to an existing project (large, gated)\n" +
|
|
248
|
+
" /asf bugfix — major bugfix (large, gated)\n" +
|
|
249
|
+
" /asf refactor — architectural refactor (large, gated)\n" +
|
|
250
|
+
" /asf small — small change, automatic (no gates)\n" +
|
|
243
251
|
" /asf status — show current phase\n" +
|
|
244
252
|
" /asf verify — run the definition-of-done QA gate\n" +
|
|
245
253
|
" /asf abort — end the current session\n\n" +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-aia-asf",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Ai Applied Agentic Software Factory — codifies the full software development flow: intake, research, spec capture, adversarial analysis, planning with approval gates, test-first implementation, and release. Requires pi-vigilant, pi-smart-web-search, pi-smart-fetch, and pi-aia-browser.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
package/skills/aia-asf/SKILL.md
CHANGED
|
@@ -4,15 +4,17 @@ description: >-
|
|
|
4
4
|
Agentic Software Factory — run a complete, disciplined software development
|
|
5
5
|
cycle. Use when the user wants to start a NEW software project, add a
|
|
6
6
|
SIGNIFICANT FEATURE to an existing project, perform a MAJOR BUGFIX, or do an
|
|
7
|
-
ARCHITECTURAL REFACTOR
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
ARCHITECTURAL REFACTOR — and also for SMALL software changes (small features,
|
|
8
|
+
minor bugfixes, small refactors), which run AUTOMATICALLY with no intake
|
|
9
|
+
questions, no PLAN.md, and no approval. LARGE work (new projects, significant
|
|
10
|
+
features, major bugfixes, architectural refactors) runs the full gated flow:
|
|
11
|
+
classify, ask until intent is clear, research SOTA and packages, capture hard
|
|
12
|
+
specifications (via capture_spec, shared with pi-vigilant), run adversarial
|
|
13
|
+
analysis, produce a PLAN.md and get explicit user approval, then implement
|
|
14
|
+
test-first with strict codebase isolation and mandatory browser testing of web
|
|
15
|
+
interfaces (pi-aia-browser). Do NOT activate for simple Q&A, one-line fixes,
|
|
16
|
+
casual conversation, content writing, or non-software tasks. When in doubt,
|
|
17
|
+
ask the user.
|
|
16
18
|
---
|
|
17
19
|
|
|
18
20
|
# AIA Agentic Software Factory (ASF)
|
|
@@ -28,24 +30,35 @@ You are running the **Ai Applied Agentic Software Factory**. This skill codifies
|
|
|
28
30
|
|
|
29
31
|
## Phase 0 — Classify the work (gate)
|
|
30
32
|
|
|
31
|
-
Determine the work type
|
|
33
|
+
Determine the work type **and scale**. If it is not ASF work, **do not run the factory** — just help normally.
|
|
32
34
|
|
|
33
|
-
| Work type | ASF? |
|
|
34
|
-
|
|
35
|
-
| New software project | ✅
|
|
36
|
-
| Significant feature
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
35
|
+
| Work type | ASF? | Scale | Flow |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| New software project | ✅ | **large** | full flow |
|
|
38
|
+
| Significant feature | ✅ | **large** | full flow (research: medium) |
|
|
39
|
+
| Small feature | ✅ | **small** | automatic |
|
|
40
|
+
| Major bugfix (multi-file, behavior change, needs tests) | ✅ | **large** | lighter flow (research optional) |
|
|
41
|
+
| Minor bugfix (one area, no contract change) | ✅ | **small** | automatic |
|
|
42
|
+
| Architectural refactor | ✅ | **large** | full flow (research: low) |
|
|
43
|
+
| Small refactor (renames, restructure of one module) | ✅ | **small** | automatic |
|
|
44
|
+
| Simple Q&A, one-liner fix, casual talk, docs-only | ❌ | — | — |
|
|
45
|
+
| Non-software tasks (LinkedIn, research-only, writing) | ❌ | — | — |
|
|
46
|
+
|
|
47
|
+
**Scale rule — the core behavior difference:**
|
|
48
|
+
|
|
49
|
+
- **Large work** runs the full gated flow: intake questions → research → specs → adversarial → PLAN.md → **explicit approval** → implementation → verification.
|
|
50
|
+
- **Small work runs automatically**: no intake question barrage (at most ONE clarifying question, only if truly ambiguous), no research, no PLAN.md, no approval gate. State the intent in one or two sentences, capture specs, implement test-first, verify, deliver. Do not ask permission to start; do not stop for sign-off. If it turns out to be larger than expected mid-way, re-classify, say so, and switch to the full flow with approval.
|
|
51
|
+
- When in doubt about scale, **default to small and start working** — the user prefers action over questions. Re-classify upward if the work grows.
|
|
41
52
|
|
|
42
53
|
If the user's request is ambiguous, **ask** before starting. State the classification explicitly:
|
|
43
|
-
`ASF: <new-project|feature|major-bugfix|refactor> — starting Phase 1 (intake).`
|
|
54
|
+
`ASF: <new-project|feature|major-bugfix|refactor> <large|small> — starting Phase 1 (intake).`
|
|
44
55
|
|
|
45
56
|
---
|
|
46
57
|
|
|
47
58
|
## Phase 1 — Intake: ask until it's clear (gate)
|
|
48
59
|
|
|
60
|
+
> **Scale check — applies to LARGE work only.** For **small** work: skip the question bank. If the request is clear enough to act, state your understanding in one or two sentences and proceed immediately. Ask at most ONE clarifying question, and only when genuinely ambiguous.
|
|
61
|
+
|
|
49
62
|
The factory **keeps asking until all is clear**. Never start planning or implementation on guesses.
|
|
50
63
|
|
|
51
64
|
Minimum intake checklist (ask anything not yet known, one question at a time or a short batch):
|
|
@@ -60,12 +73,14 @@ Minimum intake checklist (ask anything not yet known, one question at a time or
|
|
|
60
73
|
|
|
61
74
|
For each answer, **capture hard requirements immediately with `capture_spec`** (requirement, area, priority). Specs are the shared contract with pi-vigilant — it will re-verify them at the end.
|
|
62
75
|
|
|
63
|
-
**Gate 1
|
|
76
|
+
**Gate 1** (large only): You may only leave intake when the user has confirmed the summary of intent (restate it back in 3–5 bullet points and ask "is this correct?"). Small work does not pass through this gate.
|
|
64
77
|
|
|
65
78
|
---
|
|
66
79
|
|
|
67
80
|
## Phase 2 — Research: SOTA and packages (adaptive depth)
|
|
68
81
|
|
|
82
|
+
> **Small work skips research entirely.** If implementation needs a library you don't know, a single quick search is enough — no research summary, no Gate 2.
|
|
83
|
+
|
|
69
84
|
| Work type | Research depth |
|
|
70
85
|
|---|---|
|
|
71
86
|
| New project | **Mandatory, full** — SOTA approaches, frameworks, existing packages, reference implementations |
|
|
@@ -80,7 +95,7 @@ Research method (use `web_search` + `web_fetch`/`batch_web_fetch`):
|
|
|
80
95
|
4. **Cite sources** in the research summary — every claim about a package/library gets a URL
|
|
81
96
|
5. Summarize findings + a **recommendation** (which approach, which packages, with rationale)
|
|
82
97
|
|
|
83
|
-
**Gate 2
|
|
98
|
+
**Gate 2** (large only): present the research summary + recommendation to the user. Ask: "proceed with this approach, or adjust?" Do not enter planning until the approach is agreed.
|
|
84
99
|
|
|
85
100
|
---
|
|
86
101
|
|
|
@@ -94,12 +109,14 @@ Turn the intake answers + research into the authoritative spec set.
|
|
|
94
109
|
4. Default priority is `must`; use `should` only when the user says "nice to have".
|
|
95
110
|
5. Areas: functionality, ui-ux, performance, security, error-handling, testing, documentation, compatibility, constraints, format, data, deployment, other.
|
|
96
111
|
|
|
97
|
-
**Gate 3
|
|
112
|
+
**Gate 3** (large only): show the full spec tree (`get_task_specs`) and get user sign-off: "specs correct — proceed to adversarial analysis?" Small work: capture specs silently, no sign-off needed.
|
|
98
113
|
|
|
99
114
|
---
|
|
100
115
|
|
|
101
116
|
## Phase 4 — Adversarial analysis (gate)
|
|
102
117
|
|
|
118
|
+
> **Small work:** skip the formal gate. Do a quick mental pass over edge cases and failure modes while implementing; if something real surfaces, fix it or capture a spec. No user checkpoint.
|
|
119
|
+
|
|
103
120
|
Challenge the plan like a hostile reviewer before committing to it. For each spec and the overall design, ask and resolve:
|
|
104
121
|
|
|
105
122
|
- **Edge cases** — empty input, zero users, max load, missing data, concurrency
|
|
@@ -112,12 +129,14 @@ Challenge the plan like a hostile reviewer before committing to it. For each spe
|
|
|
112
129
|
|
|
113
130
|
For each finding: either capture a new spec, refine an existing one (supersede), or record the decision to accept the risk. **Ask the user about anything that changes scope.**
|
|
114
131
|
|
|
115
|
-
**Gate 4
|
|
132
|
+
**Gate 4** (large only): summarize adversarial findings + resolutions, get user confirmation.
|
|
116
133
|
|
|
117
134
|
---
|
|
118
135
|
|
|
119
136
|
## Phase 5 — Plan + approval gate
|
|
120
137
|
|
|
138
|
+
> **Small work: SKIP this phase entirely.** No PLAN.md, no approval — go straight to Phase 6 (implementation).
|
|
139
|
+
|
|
121
140
|
Write `PLAN.md` in the project root (repo root, or cwd if no repo). Structure:
|
|
122
141
|
|
|
123
142
|
```markdown
|
|
@@ -136,10 +155,10 @@ Write `PLAN.md` in the project root (repo root, or cwd if no repo). Structure:
|
|
|
136
155
|
|
|
137
156
|
Keep the plan **implementation-ready**: any competent engineer (or agent) can execute the task list without re-deriving decisions.
|
|
138
157
|
|
|
139
|
-
**Gate 5 — MANDATORY user approval**: present the plan and ask explicitly:
|
|
158
|
+
**Gate 5 — MANDATORY user approval (large only)**: present the plan and ask explicitly:
|
|
140
159
|
> "Plan ready. Do you approve starting implementation? (yes / changes needed)"
|
|
141
160
|
|
|
142
|
-
**Never start implementing before Gate 5 passes.** If the user says "go" without reading, still show the plan and confirm.
|
|
161
|
+
**Never start implementing before Gate 5 passes — for LARGE work.** If the user says "go" without reading, still show the plan and confirm. Small work never reaches this gate.
|
|
143
162
|
|
|
144
163
|
---
|
|
145
164
|
|
|
@@ -153,6 +172,14 @@ Keep the plan **implementation-ready**: any competent engineer (or agent) can ex
|
|
|
153
172
|
> **read the actual error before editing**; **verify clean-room** (caches serve stale
|
|
154
173
|
> builds); **add a regression test for every bug fixed**.
|
|
155
174
|
|
|
175
|
+
> **Read `references/06c-code-quality.md` before structuring code.** It is the mandatory
|
|
176
|
+
> modularity & maintainability standard: small well-readable modules plugged in where
|
|
177
|
+
> needed; **one implementation for shared functionality** (single escalation path,
|
|
178
|
+
> SSOT); no hardcoding (config-driven); **testable outside the host then integrated
|
|
179
|
+
> verbatim** (same modules in tests and production); refactor what is too complex to
|
|
180
|
+
> understand; layered with clear boundaries and an architecture writeup; full I/O debug
|
|
181
|
+
> logging with replay; nothing breaks existing functionality.
|
|
182
|
+
|
|
156
183
|
Execute the task list milestone by milestone. Discipline rules:
|
|
157
184
|
|
|
158
185
|
1. **Test-first**: write/update tests before or with implementation; run them; only commit green.
|
|
@@ -171,6 +198,8 @@ Execute the task list milestone by milestone. Discipline rules:
|
|
|
171
198
|
|
|
172
199
|
Run the **Definition of Done checklist** in `references/06b-testing-qa.md` (Rule 10). Every box must hold.
|
|
173
200
|
|
|
201
|
+
Also check the **modularity DoD** from `references/06c-code-quality.md` (Phase 7 section): no duplicated shared logic, no hardcoded config values, every module tested standalone with the same calls it gets in the host, architecture writeup exists, existing functionality still green.
|
|
202
|
+
|
|
174
203
|
1. Run the full test suite (all of it, not a subset); fix failures; re-run until green.
|
|
175
204
|
2. **Verify the artifact a user would actually get**: inspect the packaged file list
|
|
176
205
|
(`npm pack` → `tar tzf`), install/load it clean-room in a fresh dir with caches
|
|
@@ -201,6 +230,17 @@ Run the **Definition of Done checklist** in `references/06b-testing-qa.md` (Rule
|
|
|
201
230
|
- ❌ Guessing at a fix before reading the actual error message
|
|
202
231
|
- ❌ Fixing a bug without adding a regression test
|
|
203
232
|
- ❌ Claiming something was verified when it was assumed
|
|
233
|
+
- ❌ Asking a barrage of intake questions for small work — small runs automatically
|
|
234
|
+
- ❌ Writing PLAN.md / demanding approval for small work — that's the large-work gate only
|
|
235
|
+
- ❌ Waiting for sign-off when the work is small; when in doubt, default to small and start
|
|
236
|
+
- ❌ One giant file / god-object that "does everything" — small well-readable modules, plugged in
|
|
237
|
+
- ❌ Copy-pasting shared logic instead of importing the one authoritative module (SSOT)
|
|
238
|
+
- ❌ A "test copy" of a module that differs from the production version — same modules everywhere
|
|
239
|
+
- ❌ Hardcoding values (model names, thresholds, URLs) that config should drive
|
|
240
|
+
- ❌ Escalation/fallback logic re-implemented per caller instead of one shared escalation path
|
|
241
|
+
- ❌ Shipping a module that cannot run/test standalone outside the host
|
|
242
|
+
- ❌ Refactoring without the architecture writeup (see `references/06c-code-quality.md`)
|
|
243
|
+
- ❌ Breaking existing functionality during a refactor — refactoring preserves behavior
|
|
204
244
|
|
|
205
245
|
## References
|
|
206
246
|
|
|
@@ -210,4 +250,5 @@ Run the **Definition of Done checklist** in `references/06b-testing-qa.md` (Rule
|
|
|
210
250
|
- `references/05-plan.md` — PLAN.md template with examples
|
|
211
251
|
- `references/06-implementation.md` — coding discipline details
|
|
212
252
|
- `references/06b-testing-qa.md` — **mandatory testing & QA standard** (11 rules + definition of done)
|
|
253
|
+
- `references/06c-code-quality.md` — **mandatory modularity & maintainability standard** (8 rules, SSOT, testable-standalone, single escalation path)
|
|
213
254
|
- `references/07-release.md` — release workflow (versioning, CHANGELOG, tags, npm, CI/CD)
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Phase 1 — Intake: Question Bank
|
|
2
2
|
|
|
3
|
+
> **Scale note: this bank is for LARGE work.** Small work (small features, minor
|
|
4
|
+
> bugfixes, small refactors) skips the questions — state understanding in 1–2
|
|
5
|
+
> sentences and start. At most ONE clarifying question, only if genuinely ambiguous.
|
|
6
|
+
|
|
3
7
|
Keep asking until the user confirms. One question at a time is fine; short batches (3–5) are faster. Do not proceed on guesses.
|
|
4
8
|
|
|
5
9
|
## Starter questions
|
|
@@ -32,3 +36,5 @@ Every concrete requirement the user states → `capture_spec` immediately, befor
|
|
|
32
36
|
## Intake gate
|
|
33
37
|
|
|
34
38
|
Restate intent in 3–5 bullets, then ask: **"Is this correct?"** Only proceed on an explicit yes.
|
|
39
|
+
|
|
40
|
+
> Large work only. Small work has no intake gate.
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
# Phase 4 — Adversarial Analysis Checklist
|
|
2
2
|
|
|
3
|
+
> **Scale note: the full checklist and gate apply to LARGE work.** Small work does
|
|
4
|
+
> a quick mental pass on edge cases and failure modes while implementing — no
|
|
5
|
+
> formal review, no user checkpoint.
|
|
6
|
+
|
|
3
7
|
Challenge every spec and design decision like a hostile reviewer. For each item, determine: capture a new spec / supersede an existing one / accept the risk (recorded).
|
|
4
8
|
|
|
5
9
|
## Per-spec questions
|
|
6
10
|
|
|
11
|
+
> **Code-quality lens (always applied):** for every module/design under review,
|
|
12
|
+
> also ask the `references/06c-code-quality.md` questions — is shared logic
|
|
13
|
+
> duplicated anywhere? Is the single escalation path identifiable? Is the module
|
|
14
|
+
> testable standalone with the same calls? Any hardcoded values that belong in
|
|
15
|
+
> config?
|
|
16
|
+
|
|
7
17
|
- **Edge cases**: empty input, zero data, max load, missing fields, concurrent access, duplicate input, unicode, huge payloads
|
|
8
18
|
- **Failure modes**: what breaks first? Is failure loud or silent? Can we recover automatically?
|
|
9
19
|
- **Security**: authentication, authorization, injection (SQL/XSS), data exposure, secrets, abuse/rate-limiting, supply chain
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Phase 5 — PLAN.md Template
|
|
2
2
|
|
|
3
|
+
> **Scale note: this phase is for LARGE work only.** Small work skips PLAN.md and
|
|
4
|
+
> the approval gate entirely — implement directly.
|
|
5
|
+
|
|
3
6
|
Write `PLAN.md` in the project root. It must be executable by any competent engineer without re-deriving decisions.
|
|
4
7
|
|
|
5
8
|
```markdown
|
|
@@ -18,10 +21,13 @@ Existing system, repo layout, relevant prior work. Links to research sources.
|
|
|
18
21
|
Decided approach with rationale. Cite the research (package names, URLs).
|
|
19
22
|
|
|
20
23
|
## Architecture / Design
|
|
21
|
-
-
|
|
24
|
+
- Modules and their responsibilities (small, single-purpose — see `references/06c-code-quality.md`)
|
|
22
25
|
- Data model / schema (if any)
|
|
23
26
|
- Key flows (request lifecycle, event flow)
|
|
24
27
|
- Interfaces / contracts between components
|
|
28
|
+
- **Where shared truth lives** (single source of truth map: which module owns each shared capability)
|
|
29
|
+
- **Layering**: one-way dependency rules between layers; what each layer may/may not import
|
|
30
|
+
- **Standalone testability**: how each module is exercised outside the host with the same calls
|
|
25
31
|
|
|
26
32
|
## Milestones
|
|
27
33
|
| # | Milestone | Exit criteria |
|
|
@@ -54,7 +60,7 @@ From adversarial analysis. Each risk: likelihood, impact, mitigation, owner.
|
|
|
54
60
|
Explicitly cut items (so nobody re-adds them).
|
|
55
61
|
```
|
|
56
62
|
|
|
57
|
-
## Approval gate (MANDATORY)
|
|
63
|
+
## Approval gate (MANDATORY — large work only)
|
|
58
64
|
|
|
59
65
|
Present the plan and ask:
|
|
60
66
|
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Phase 6 — Implementation Discipline
|
|
2
2
|
|
|
3
|
+
> **Also read `references/06c-code-quality.md`** — the modularity & maintainability
|
|
4
|
+
> standard. Structure code as small modules with one responsibility, keep shared
|
|
5
|
+
> functionality in exactly one implementation (SSOT, single escalation path),
|
|
6
|
+
> never hardcode what config should drive, and keep every module testable
|
|
7
|
+
> standalone outside the host.
|
|
8
|
+
|
|
3
9
|
## Test-first
|
|
4
10
|
|
|
5
11
|
1. Write the failing test for the next behavior
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Modularity & Maintainability Standard (MANDATORY)
|
|
2
|
+
|
|
3
|
+
Distilled from Bruno's own development philosophy — honed on the Tunnel project
|
|
4
|
+
and its modules (smart-router, autoroute, feature-extractor, heuristic-engine) —
|
|
5
|
+
and reinforced by established software-engineering research: **Single Source of
|
|
6
|
+
Truth (SSOT)**, **testability as a design property**, and **ports-and-adapters
|
|
7
|
+
(hexagonal) seams**.
|
|
8
|
+
|
|
9
|
+
These rules exist because violating them caused real pain in those sessions:
|
|
10
|
+
code "thrown on a heap", duplicated logic, hardcoded model attributes, modules
|
|
11
|
+
that could not be tested outside the server, and regressions that broke
|
|
12
|
+
existing functionality. Each rule below carries the lesson.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Rule 1 — Small, well-readable modules, plugged in where needed
|
|
17
|
+
|
|
18
|
+
> *"You throw a bunch of code and functionality on a heap, instead of making
|
|
19
|
+
> smaller, well-readable modules and plugging them in where needed."* — Tunnel sessions
|
|
20
|
+
|
|
21
|
+
- One module = one responsibility. If a file does two unrelated things, split it.
|
|
22
|
+
- A module must be **readable top to bottom** by someone new: clear names,
|
|
23
|
+
short functions, no 500-line god-files.
|
|
24
|
+
- **Plug in, don't embed**: the host system imports and wires modules; it does
|
|
25
|
+
not copy their logic inline.
|
|
26
|
+
- Extraction triggers (any of these → extract a module):
|
|
27
|
+
- a function/concern exceeds ~100 lines or 3 levels of nesting
|
|
28
|
+
- the same logic is needed by two call sites
|
|
29
|
+
- you cannot explain what the file does in one sentence
|
|
30
|
+
- you are about to debug the same area a second time
|
|
31
|
+
|
|
32
|
+
## Rule 2 — One implementation for shared functionality (single escalation path)
|
|
33
|
+
|
|
34
|
+
> *"Make a separate module for ... communication and use IT instead of having
|
|
35
|
+
> that function integrated in there."* — Tunnel sessions
|
|
36
|
+
|
|
37
|
+
- **Every shared capability lives in exactly one authoritative module.**
|
|
38
|
+
Everything else imports it. No copies, no re-implementations, no
|
|
39
|
+
"parallel systems working side by side" (*"I want an integrated system, not a
|
|
40
|
+
dual system working side by side"*).
|
|
41
|
+
- This is the **Single Source of Truth** (SSOT) principle: every piece of
|
|
42
|
+
knowledge exists in exactly one place; every other reference *points* to it.
|
|
43
|
+
- SSOT checklist before shipping (from research on SSOT):
|
|
44
|
+
- Is any value/logic defined in more than one place?
|
|
45
|
+
- If this changes tomorrow, how many files do I touch? (Answer: **one**.)
|
|
46
|
+
- Would a new developer know where the authoritative version lives?
|
|
47
|
+
- Escalation paths included: if a request can escalate (to a stronger model,
|
|
48
|
+
a fallback, a retry, an admin), there is **one** escalation path module that
|
|
49
|
+
every caller routes through — not ad-hoc escalation logic scattered per
|
|
50
|
+
caller.
|
|
51
|
+
|
|
52
|
+
## Rule 3 — No hardcoding; config drives behavior
|
|
53
|
+
|
|
54
|
+
> *"DO NOT hard-code attributes of models ... stuff in the brackets is specific
|
|
55
|
+
> to opus, but not necessarily to any model we will add."* — Tunnel sessions
|
|
56
|
+
|
|
57
|
+
- Model names, thresholds, limits, timeouts, URLs, feature flags: all load from
|
|
58
|
+
config, never literal in logic.
|
|
59
|
+
- If you hardcode a value that another system (or a future system) might share,
|
|
60
|
+
you have created a second source of truth — see Rule 2.
|
|
61
|
+
- The module must behave the same for any config input; its logic is
|
|
62
|
+
config-agnostic.
|
|
63
|
+
|
|
64
|
+
## Rule 4 — Testable outside the host, then integrated verbatim
|
|
65
|
+
|
|
66
|
+
> *"MAKE IT TIGHT AND MODULAR AND FULLY TESTABLE OUTSIDE OF THE SERVER. TEST
|
|
67
|
+
> EVERYTHING 100% ANALOGOUS TO HOW IT WORKS ON THE SERVER ... THEN INTEGRATE
|
|
68
|
+
> BACK INTO THE SERVER."* — Tunnel sessions
|
|
69
|
+
|
|
70
|
+
- A module must run standalone: a test script imports and primes it **with the
|
|
71
|
+
exact same calls** the host would make.
|
|
72
|
+
- **Same modules in tests and production** — never a "test copy" of logic.
|
|
73
|
+
Tests import the production module; the host imports the same module.
|
|
74
|
+
(*"It should be imported in [the host] and used there with no changes — a
|
|
75
|
+
separate test script importing and priming the module can be created for
|
|
76
|
+
testing."*)
|
|
77
|
+
- **Testability is a design property, not a testing task** (research): if a
|
|
78
|
+
business rule needs a running server + real DB to validate, the architecture
|
|
79
|
+
is wrong. Core logic should run as plain functions with injected fakes.
|
|
80
|
+
- Build **seams** (ports-and-adapters): core logic depends on interfaces
|
|
81
|
+
(clock, IDs, persistence, external calls, message publishing), not on
|
|
82
|
+
concrete infrastructure. Adapters live at the edge.
|
|
83
|
+
- Verification flow: develop → test standalone (100% analogous) → **integrate
|
|
84
|
+
into the host verbatim** → re-test in place.
|
|
85
|
+
|
|
86
|
+
## Rule 5 — Refactor what is too complex to understand
|
|
87
|
+
|
|
88
|
+
> *"REFACTOR WHAT IS TOO COMPLEX FOR YOU TO UNDERSTAND!"* — Tunnel sessions
|
|
89
|
+
|
|
90
|
+
- Complexity you cannot explain is a defect, not a badge of honor.
|
|
91
|
+
- When you find yourself running "rounds like a moron" debugging something,
|
|
92
|
+
**stop and refactor the module** instead of patching blind.
|
|
93
|
+
- Refactor gate (when to invest): only refactor when it makes debugging and
|
|
94
|
+
individual component testing easier and faster, with the data you already
|
|
95
|
+
have. Not refactoring for its own sake; refactoring for **testability and
|
|
96
|
+
clarity**.
|
|
97
|
+
- Refactoring techniques that directly serve this (research-validated):
|
|
98
|
+
**Extract Method** (break long functions into named steps), **Extract Class/
|
|
99
|
+
Module** (group related logic), **Replace Conditional with Polymorphism**
|
|
100
|
+
(turn nested conditionals into modular dispatch), **Remove Duplication**
|
|
101
|
+
(collapse copies into one implementation).
|
|
102
|
+
|
|
103
|
+
## Rule 6 — Layer with clear boundaries, and document them
|
|
104
|
+
|
|
105
|
+
> *"Refactor the layering for readability completely, test everything in
|
|
106
|
+
> detail, and do a writeup for the layered system."* — Tunnel sessions
|
|
107
|
+
|
|
108
|
+
- Define layers (e.g., handler → router → modules → backends) with one-way
|
|
109
|
+
dependency rules. No layer reaches across another.
|
|
110
|
+
- **Do a writeup**: a short architecture doc (in the repo) stating what each
|
|
111
|
+
module is, what it uses, how and why, and where truth lives (the SSOT map).
|
|
112
|
+
(*"Properly document the modules and the main scaffolding to always have a
|
|
113
|
+
clear idea what is happening where."*)
|
|
114
|
+
- Research on architecture fitness: keep the "core" boring and deterministic
|
|
115
|
+
(no framework/IO inside); edges translate to and from infrastructure.
|
|
116
|
+
|
|
117
|
+
## Rule 7 — Debug observability: full I/O logging, replayable
|
|
118
|
+
|
|
119
|
+
> *"Shouldn't you also log somewhere the FULL input and outputs of the whole
|
|
120
|
+
> chain (during debug only) including headers and bodies ... and then
|
|
121
|
+
> comparing, since the lateral test just works?"* — Tunnel sessions
|
|
122
|
+
|
|
123
|
+
- During debug: log the **full input and output of the whole chain** (headers,
|
|
124
|
+
bodies, intermediate steps) to disk — not just errors.
|
|
125
|
+
- Side tests must log identically, so you can **compare** a passing lateral
|
|
126
|
+
test against a failing production call and see the divergence.
|
|
127
|
+
- Keep captured real traffic and **replay it through the structure**
|
|
128
|
+
(*"using stored message data and replaying it through the structure"*) to
|
|
129
|
+
reproduce and fix without the live host.
|
|
130
|
+
- Logging must be enough that long-term debugging works from log files and the
|
|
131
|
+
stored corpus alone.
|
|
132
|
+
|
|
133
|
+
## Rule 8 — Nothing may break existing functionality
|
|
134
|
+
|
|
135
|
+
> *"Nothing may break already existing functionality in the server."* — Tunnel sessions
|
|
136
|
+
|
|
137
|
+
- Modularity changes and refactors are **behavior-preserving**: same inputs,
|
|
138
|
+
same outputs, same side effects.
|
|
139
|
+
- After any restructuring, run the existing tests + a regression pass over the
|
|
140
|
+
previous behavior before declaring done.
|
|
141
|
+
- This is the SSOT/refactor safety net: refactoring restructures *structure*,
|
|
142
|
+
never *behavior*.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Where this applies in ASF
|
|
147
|
+
|
|
148
|
+
- **Phase 4 (adversarial)**: challenge the design — is there duplication?
|
|
149
|
+
Where is the single source of truth? Is the module testable outside the
|
|
150
|
+
host? What breaks if a config value changes?
|
|
151
|
+
- **Phase 5 (PLAN.md)**: the Architecture/Design section must name the modules,
|
|
152
|
+
their boundaries, the one-way dependencies, where shared truth lives, and
|
|
153
|
+
how each module is tested standalone.
|
|
154
|
+
- **Phase 6 (implementation)**: apply Rules 1–8 as you build; extract modules
|
|
155
|
+
when triggers fire; write the architecture doc alongside the code.
|
|
156
|
+
- **Phase 7 (verification)**: the DoD checklist includes: no duplicated shared
|
|
157
|
+
logic (Rule 2), no hardcoded config values (Rule 3), every module tested
|
|
158
|
+
standalone with the same calls (Rule 4), architecture doc written (Rule 6),
|
|
159
|
+
existing functionality still green (Rule 8).
|
|
160
|
+
|
|
161
|
+
## Anti-patterns
|
|
162
|
+
|
|
163
|
+
- ❌ One giant file / god-object that "does everything"
|
|
164
|
+
- ❌ Copy-pasting shared logic instead of importing the one module
|
|
165
|
+
- ❌ A "test version" of a module that differs from the production version
|
|
166
|
+
- ❌ Hardcoded model names, thresholds, URLs in logic instead of config
|
|
167
|
+
- ❌ Escalation/fallback logic re-implemented per caller instead of one path
|
|
168
|
+
- ❌ Refactoring "for fun" without the testability/debugging payoff
|
|
169
|
+
- ❌ Shipping a module that cannot run outside the host
|
|
170
|
+
- ❌ Skipping the architecture writeup ("the code is self-documenting")
|