opencode-overclock 0.4.0 → 0.5.0
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/README.md +63 -17
- package/package.json +5 -3
- package/skills/codebase-design/DEEPENING.md +35 -0
- package/skills/codebase-design/DESIGN-IT-TWICE.md +34 -0
- package/skills/codebase-design/SKILL.md +93 -0
- package/skills/diagnosing-bugs/SKILL.md +123 -0
- package/skills/domain-modeling/ADR-FORMAT.md +55 -0
- package/skills/domain-modeling/CONTEXT-FORMAT.md +32 -0
- package/skills/domain-modeling/SKILL.md +102 -0
- package/skills/doubt/SKILL.md +80 -0
- package/skills/grilling/SKILL.md +96 -0
- package/skills/source-discipline/SKILL.md +78 -0
- package/skills/tdd/SKILL.md +87 -0
- package/skills/to-spec/SKILL.md +69 -0
- package/skills/to-spec/SPEC-TEMPLATE.md +50 -0
- package/skills/to-tickets/SKILL.md +74 -0
- package/skills/to-tickets/TICKET-TEMPLATE.md +41 -0
- package/src/core/lifecycle.ts +18 -4
- package/src/core/types.ts +29 -0
- package/src/features/guard.ts +258 -12
- package/src/features/index.ts +13 -1
- package/src/features/recovery.ts +13 -3
- package/src/features/safety.ts +147 -0
- package/src/features/sched.ts +46 -10
- package/src/features/tasks.ts +87 -20
- package/src/features/truncator.ts +26 -9
- package/src/features/usage.ts +20 -0
- package/src/features/workflow.ts +256 -0
- package/src/lib/exec.ts +7 -1
- package/src/platform/process/exec.ts +252 -11
- package/src/platform/session/inject.ts +8 -1
- package/src/platform/storage/state.ts +26 -4
- package/src/v2/host.ts +4 -1
- package/src/workflow/agents/codebase-researcher.ts +27 -0
- package/src/workflow/agents/design-explorer.ts +33 -0
- package/src/workflow/agents/doubt-reviewer.ts +26 -0
- package/src/workflow/agents/engineering-coach.ts +23 -0
- package/src/workflow/agents/performance-auditor.ts +29 -0
- package/src/workflow/agents/security-auditor.ts +23 -0
- package/src/workflow/agents/spec-reviewer.ts +15 -0
- package/src/workflow/agents/standards-reviewer.ts +24 -0
- package/src/workflow/agents/test-engineer.ts +28 -0
- package/src/workflow/catalog.ts +210 -0
- package/src/workflow/templates/build.ts +47 -0
- package/src/workflow/templates/define.ts +45 -0
- package/src/workflow/templates/diagnose.ts +58 -0
- package/src/workflow/templates/plan.ts +52 -0
- package/src/workflow/templates/ship.ts +64 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
|
2
|
+
import { dirname, basename, resolve } from "node:path"
|
|
3
|
+
import YAML from "yaml"
|
|
4
|
+
|
|
5
|
+
export interface SkillMetadata {
|
|
6
|
+
name: string
|
|
7
|
+
description: string
|
|
8
|
+
pack?: string
|
|
9
|
+
license?: string
|
|
10
|
+
attribution?: string
|
|
11
|
+
references?: string[]
|
|
12
|
+
[key: string]: unknown
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ParsedSkill {
|
|
16
|
+
filePath: string
|
|
17
|
+
directory: string
|
|
18
|
+
metadata: SkillMetadata
|
|
19
|
+
body: string
|
|
20
|
+
rawFrontmatter: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SkillValidationError {
|
|
24
|
+
filePath: string
|
|
25
|
+
message: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Extracts and parses YAML frontmatter with strict duplicate key checking.
|
|
32
|
+
*/
|
|
33
|
+
export function parseFrontmatter(
|
|
34
|
+
content: string,
|
|
35
|
+
filePath = "<string>",
|
|
36
|
+
): { metadata: SkillMetadata; body: string; rawFrontmatter: string } {
|
|
37
|
+
const match = content.match(FRONTMATTER_REGEX)
|
|
38
|
+
if (!match) {
|
|
39
|
+
throw new Error(`Missing frontmatter delimiter (---) in ${filePath}`)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const rawFrontmatter = match[1]!
|
|
43
|
+
const body = match[2]!
|
|
44
|
+
|
|
45
|
+
let parsed: unknown
|
|
46
|
+
try {
|
|
47
|
+
parsed = YAML.parse(rawFrontmatter, { uniqueKeys: true })
|
|
48
|
+
} catch (err: any) {
|
|
49
|
+
throw new Error(`Invalid YAML frontmatter in ${filePath}: ${err?.message ?? String(err)}`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
53
|
+
throw new Error(`Frontmatter must be a key-value mapping in ${filePath}`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const data = parsed as Record<string, unknown>
|
|
57
|
+
|
|
58
|
+
if (typeof data.name !== "string" || !data.name.trim()) {
|
|
59
|
+
throw new Error(`Skill frontmatter missing required string "name" in ${filePath}`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const name = data.name.trim()
|
|
63
|
+
if (!/^[a-z0-9_-]+$/.test(name)) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Invalid skill name "${name}" in ${filePath}: must be lowercase alphanumeric with dashes or underscores`,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof data.description !== "string" || data.description.trim().length < 10) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Skill frontmatter "description" in ${filePath} must be a descriptive string (at least 10 characters)`,
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const metadata: SkillMetadata = {
|
|
76
|
+
...data,
|
|
77
|
+
name,
|
|
78
|
+
description: data.description.trim(),
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { metadata, body, rawFrontmatter }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Validates a single SKILL.md file for schema compliance, directory matching,
|
|
86
|
+
* and relative reference closure.
|
|
87
|
+
*/
|
|
88
|
+
export function validateSkillFile(filePath: string): {
|
|
89
|
+
valid: boolean
|
|
90
|
+
errors: string[]
|
|
91
|
+
skill?: ParsedSkill
|
|
92
|
+
} {
|
|
93
|
+
const errors: string[] = []
|
|
94
|
+
|
|
95
|
+
if (!existsSync(filePath)) {
|
|
96
|
+
return { valid: false, errors: [`File does not exist: ${filePath}`] }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let content = ""
|
|
100
|
+
try {
|
|
101
|
+
content = readFileSync(filePath, "utf-8")
|
|
102
|
+
} catch (err: any) {
|
|
103
|
+
return { valid: false, errors: [`Failed to read file ${filePath}: ${err?.message}`] }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let parsed: { metadata: SkillMetadata; body: string; rawFrontmatter: string }
|
|
107
|
+
try {
|
|
108
|
+
parsed = parseFrontmatter(content, filePath)
|
|
109
|
+
} catch (err: any) {
|
|
110
|
+
return { valid: false, errors: [err?.message ?? String(err)] }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const skillDir = dirname(filePath)
|
|
114
|
+
const dirName = basename(skillDir)
|
|
115
|
+
|
|
116
|
+
if (parsed.metadata.name !== dirName) {
|
|
117
|
+
errors.push(
|
|
118
|
+
`Skill name mismatch in ${filePath}: declared "${parsed.metadata.name}" but parent directory is "${dirName}"`,
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Validate declared references
|
|
123
|
+
if (parsed.metadata.references) {
|
|
124
|
+
if (!Array.isArray(parsed.metadata.references)) {
|
|
125
|
+
errors.push(`"references" in ${filePath} must be an array of relative paths`)
|
|
126
|
+
} else {
|
|
127
|
+
for (const ref of parsed.metadata.references) {
|
|
128
|
+
if (typeof ref !== "string") {
|
|
129
|
+
errors.push(`Invalid reference in ${filePath}: expected string, got ${typeof ref}`)
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
const resolvedRef = resolve(skillDir, ref)
|
|
133
|
+
if (!existsSync(resolvedRef)) {
|
|
134
|
+
errors.push(`Declared reference not found in ${filePath}: "${ref}" -> ${resolvedRef}`)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check markdown links to local files (dependency closure)
|
|
141
|
+
const linkRegex = /\[[^\]]+\]\((?!https?:\/\/|#|mailto:)([^)#?]+)\)/g
|
|
142
|
+
let match: RegExpExecArray | null
|
|
143
|
+
while ((match = linkRegex.exec(parsed.body)) !== null) {
|
|
144
|
+
const target = match[1]?.trim()
|
|
145
|
+
if (!target) continue
|
|
146
|
+
const resolvedLink = resolve(skillDir, target)
|
|
147
|
+
if (!existsSync(resolvedLink)) {
|
|
148
|
+
errors.push(`Broken local markdown link in ${filePath}: "${target}" -> ${resolvedLink}`)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (errors.length > 0) {
|
|
153
|
+
return { valid: false, errors }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
valid: true,
|
|
158
|
+
errors: [],
|
|
159
|
+
skill: {
|
|
160
|
+
filePath,
|
|
161
|
+
directory: skillDir,
|
|
162
|
+
metadata: parsed.metadata,
|
|
163
|
+
body: parsed.body,
|
|
164
|
+
rawFrontmatter: parsed.rawFrontmatter,
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Validates all skills within the bundled skills directory.
|
|
171
|
+
*/
|
|
172
|
+
export function validateAllSkills(skillsDir: string): {
|
|
173
|
+
valid: boolean
|
|
174
|
+
errors: SkillValidationError[]
|
|
175
|
+
skills: ParsedSkill[]
|
|
176
|
+
} {
|
|
177
|
+
const errors: SkillValidationError[] = []
|
|
178
|
+
const skills: ParsedSkill[] = []
|
|
179
|
+
|
|
180
|
+
if (!existsSync(skillsDir)) {
|
|
181
|
+
return {
|
|
182
|
+
valid: false,
|
|
183
|
+
errors: [{ filePath: skillsDir, message: `Skills directory does not exist: ${skillsDir}` }],
|
|
184
|
+
skills: [],
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const entries = readdirSync(skillsDir, { withFileTypes: true })
|
|
189
|
+
for (const entry of entries) {
|
|
190
|
+
if (entry.isDirectory()) {
|
|
191
|
+
const skillFile = resolve(skillsDir, entry.name, "SKILL.md")
|
|
192
|
+
if (existsSync(skillFile)) {
|
|
193
|
+
const result = validateSkillFile(skillFile)
|
|
194
|
+
if (result.valid && result.skill) {
|
|
195
|
+
skills.push(result.skill)
|
|
196
|
+
} else {
|
|
197
|
+
for (const err of result.errors) {
|
|
198
|
+
errors.push({ filePath: skillFile, message: err })
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
valid: errors.length === 0,
|
|
207
|
+
errors,
|
|
208
|
+
skills,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const BUILD_TEMPLATE = `---
|
|
2
|
+
description: Test-driven implementation loop with stop-the-line tripwires and incremental verification.
|
|
3
|
+
---
|
|
4
|
+
# Lifecycle Phase 3: Build
|
|
5
|
+
|
|
6
|
+
Execute tasks from \`tasks/plan.md\` (or the specific task requested: $ARGUMENTS).
|
|
7
|
+
|
|
8
|
+
## Autonomous Mode ($ARGUMENTS contains "auto") vs Single-Slice Mode
|
|
9
|
+
- **With \`auto\`:** Iteratively execute all unblocked tasks from \`tasks/plan.md\` sequentially until all are complete or a tripwire triggers.
|
|
10
|
+
- **Without \`auto\` (Default):** Execute only the next unblocked task on the frontier, verify, and pause for human review.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Increment Cycle (Per Task)
|
|
15
|
+
|
|
16
|
+
For each task on the frontier:
|
|
17
|
+
|
|
18
|
+
1. **RED (Prove Capability Missing):**
|
|
19
|
+
- Write a focused test at the declared public seam before touching implementation code.
|
|
20
|
+
- Use an **independent test oracle**: never compute expected results with the same logic used in production code.
|
|
21
|
+
- Run the test suite: confirm the test fails for the expected reason (missing capability, not a syntax error).
|
|
22
|
+
- *Prove-It Pattern:* If fixing a bug, the test MUST reproduce the reported defect before touching the fix.
|
|
23
|
+
|
|
24
|
+
2. **GREEN (Minimal Implementation):**
|
|
25
|
+
- Write the minimal code required to make the test pass clean.
|
|
26
|
+
- Do NOT add speculative abstractions or unrequested features.
|
|
27
|
+
- Never use error suppressions (\`@ts-ignore\`, \`eslint-disable\`, \`# noqa\`) or test skips (\`.skip\`). Overclock's floor-guard will flag them.
|
|
28
|
+
|
|
29
|
+
3. **REFACTOR (Clean While Green):**
|
|
30
|
+
- Refactor only while all tests are green.
|
|
31
|
+
- Remove duplication, simplify names, and polish structure. Re-verify tests pass after every refactoring edit.
|
|
32
|
+
|
|
33
|
+
4. **VERIFY:**
|
|
34
|
+
- Run project linters and typecheckers to confirm zero regressions.
|
|
35
|
+
|
|
36
|
+
5. **UPDATE PLAN:**
|
|
37
|
+
- Mark the completed task in \`tasks/plan.md\` and update \`todowrite\`.
|
|
38
|
+
- If git commits are used, stage ONLY the files modified for this slice with a descriptive commit message.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Stop-The-Line Tripwires (Immediate Halt)
|
|
43
|
+
Halt execution and alert the user immediately if:
|
|
44
|
+
- **Test Failure Loop:** A test fails to pass after 3 consecutive fix attempts.
|
|
45
|
+
- **Irreversible Boundary:** The task requires altering production database schemas, payment processing, or secret keys.
|
|
46
|
+
- **Specification Ambiguity:** An unhandled edge case is discovered that contradicts \`SPEC.md\` or requires human judgment.
|
|
47
|
+
`
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const DEFINE_TEMPLATE = `---
|
|
2
|
+
description: Interrogate requirements or synthesize formal SPEC.md using the grilling and domain-modeling protocols.
|
|
3
|
+
---
|
|
4
|
+
# Lifecycle Phase 1: Define
|
|
5
|
+
|
|
6
|
+
You are conducting the Define phase for: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
Assess current context before acting:
|
|
9
|
+
- **Mode A: Interview (Grilling & Domain Modeling):** If requirements are broad, ambiguous, or unstated, conduct structured inquiry.
|
|
10
|
+
- **Mode B: Synthesis (To-Spec):** If requirements, architecture, or features were ALREADY discussed and settled in conversation, do NOT restart interview rounds. Jump straight to synthesizing \`SPEC.md\`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Mode A: The Grilling & Domain Modeling Protocol
|
|
15
|
+
Do NOT write production code. Act as a senior software architect interrogating requirements:
|
|
16
|
+
|
|
17
|
+
1. **Discover Facts First:** Use tools (\`read\`, \`glob\`, \`grep\`) to inspect existing models, dependencies, and code conventions yourself. Never ask the user for information discoverable from the repository.
|
|
18
|
+
2. **Challenge Overloaded Terms:** Align on ubiquitous language. If terms like "user" or "account" are ambiguous, sharpen them into canonical terms and record them in \`CONTEXT.md\`.
|
|
19
|
+
3. **Dependency-Ordered Rounds:** Group questions on the unblocked decision frontier (max 3-4 numbered questions per turn). Resolve fundamental architecture (storage, security) before downstream details.
|
|
20
|
+
4. **The Recommended Defaults Rule (➡️):** For EVERY question you ask, you MUST provide an opinionated default recommendation:
|
|
21
|
+
\`\`\`markdown
|
|
22
|
+
1. Where should idempotency keys be stored and for what TTL?
|
|
23
|
+
➡️ **Recommended:** Redis cache with 24-hour TTL, matching session storage conventions.
|
|
24
|
+
\`\`\`
|
|
25
|
+
This allows the user to approve with "LGTM", "accept recommendations", or override individual points.
|
|
26
|
+
5. **Establish 3-Tier Boundaries:**
|
|
27
|
+
- **Always Do:** Non-negotiables (invariants, validations, mandatory audit logs).
|
|
28
|
+
- **Ask First:** Irreversible actions (schema drops, payment operations, external contracts).
|
|
29
|
+
- **Never Do:** Prohibited anti-patterns (floating-point currency, skipping auth).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Mode B: Specification Synthesis (Output: SPEC.md)
|
|
34
|
+
Once requirements are clear, write or update \`SPEC.md\` (or the project's designated spec location):
|
|
35
|
+
|
|
36
|
+
- **1. Problem Statement & Solution:** High-level problem and user-perspective solution.
|
|
37
|
+
- **2. Ubiquitous Language:** Canonical domain terms from \`CONTEXT.md\`.
|
|
38
|
+
- **3. User Stories & Acceptance Criteria:** Numbered list with verifiable Given/When/Then outcomes.
|
|
39
|
+
- **4. Public Seams & Interfaces:** Explicit signatures, route types, and invariant contracts.
|
|
40
|
+
- **5. 3-Tier Boundaries:** Always Do / Ask First / Never Do.
|
|
41
|
+
- **6. Out of Scope (Non-Goals):** Concrete exclusions preventing scope creep.
|
|
42
|
+
- **7. Verification Strategy:** Automated commands (tests, smoke runs) proving completion.
|
|
43
|
+
|
|
44
|
+
Prompt the user to review and confirm \`SPEC.md\`. Once approved, direct them to run \`/plan\`.
|
|
45
|
+
`
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const DIAGNOSE_TEMPLATE = `---
|
|
2
|
+
description: Disciplined root-cause diagnosis loop with red-capable feedback loops, tagged logs, and regression guards.
|
|
3
|
+
---
|
|
4
|
+
# Lifecycle Phase 4: Diagnose
|
|
5
|
+
|
|
6
|
+
Investigate and fix the reported bug or defect: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
## Scope Check: Explanation vs Deep Investigation
|
|
9
|
+
- **Explanation:** If the user is asking for a conceptual explanation of an error, provide a direct answer.
|
|
10
|
+
- **Deep Investigation:** If diagnosing a defect, crash, flake, or regression, execute the 6-phase loop below.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 0. Secret Redaction First
|
|
15
|
+
Before displaying commands, outputs, or traces:
|
|
16
|
+
- Replace credentials, authorization headers, tokens, and private keys with \`<REDACTED>\`.
|
|
17
|
+
- Keep secrets in environment variables rather than command strings.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The 6-Phase Diagnostic Loop
|
|
22
|
+
|
|
23
|
+
### Phase 1: Construct the Tight Feedback Loop
|
|
24
|
+
DO NOT speculate, theorize, or edit production code yet.
|
|
25
|
+
Construct an automated command (unit test, curl, CLI invocation, or trace replay) that reliably triggers the failure.
|
|
26
|
+
- **Deterministic:** Runs unattended and produces a clear pass/fail signal.
|
|
27
|
+
- **Fast:** Executes in seconds.
|
|
28
|
+
- **Flaky / Intermittent Defects:** Loop the trigger 50-100 times under load to raise the reproduction rate. A 40%-flake bug is debuggable; a 0.5% flake is not.
|
|
29
|
+
- **Inaccessible Environments:** If missing credentials or remote environments prevent local repro, do NOT guess. State what is missing and ask the user for a sanitized HAR trace, log dump, or temporary staging instrumentation.
|
|
30
|
+
|
|
31
|
+
### Phase 2: Reproduce & Minimise
|
|
32
|
+
1. Run the loop and confirm Red: verify the failure matches the **user's actual symptom**.
|
|
33
|
+
2. **Minimise:** Cut parameters, configurations, and data one at a time until every remaining line is load-bearing.
|
|
34
|
+
|
|
35
|
+
### Phase 3: Ranked Falsifiable Hypotheses
|
|
36
|
+
Formulate 3 to 5 distinct, ranked hypotheses. For each hypothesis, state its prediction:
|
|
37
|
+
> _"If [Cause X] is the root cause, then [Changing Y] will resolve the failure, and [Changing Z] will worsen it."_
|
|
38
|
+
|
|
39
|
+
### Phase 4: Instrument with Tagged Probes
|
|
40
|
+
1. Test predictions changing ONE variable at a time.
|
|
41
|
+
2. Tag all diagnostic logging with unique searchable tags:
|
|
42
|
+
\`\`\`ts
|
|
43
|
+
console.log("[DEBUG-d8a1] Received payload:", payload)
|
|
44
|
+
\`\`\`
|
|
45
|
+
3. **Performance Regressions:** Do not use console logs (they distort timing). Measure with stable baselines first, bisect, and compare.
|
|
46
|
+
|
|
47
|
+
### Phase 5: Fix & Permanent Regression Guard
|
|
48
|
+
1. Write a permanent regression test at the public seam **before** the fix.
|
|
49
|
+
*(If the codebase architecture lacks a clean seam to test this bug, document it as an architectural finding).*
|
|
50
|
+
2. Apply the minimal root-cause fix. Never paper over symptoms or swallow errors.
|
|
51
|
+
3. Assert Green on the regression test.
|
|
52
|
+
4. Re-run the Phase 1 loop against the full original scenario.
|
|
53
|
+
|
|
54
|
+
### Phase 6: Clean Up & Verify
|
|
55
|
+
1. Remove all \`[DEBUG-xxxx]\` logging statements (\`grep\` for the tag).
|
|
56
|
+
2. Clean up temporary reproduction scripts.
|
|
57
|
+
3. Run project linters and test suites to verify zero regressions.
|
|
58
|
+
`
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const PLAN_TEMPLATE = `---
|
|
2
|
+
description: Decompose SPEC.md into vertical tracer-bullet tasks in tasks/plan.md with dependency DAG.
|
|
3
|
+
---
|
|
4
|
+
# Lifecycle Phase 2: Plan
|
|
5
|
+
|
|
6
|
+
You are decomposing \`SPEC.md\` (or agreed design) into an executable dependency plan for: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
## Core Decomposition Principles
|
|
9
|
+
|
|
10
|
+
1. **Prefactoring First:** Look for opportunities to refactor existing code before implementing new logic:
|
|
11
|
+
> _"Make the change easy, then make the easy change."_ (Kent Beck)
|
|
12
|
+
If prefactoring is needed, schedule it as Task 1 on the frontier.
|
|
13
|
+
2. **Vertical Tracer Bullets:** Every task must cut a narrow but complete path through data, logic, interface, and tests. Avoid horizontal layer-by-layer batches (e.g. "all schemas first"). Each completed task delivers verifiable, working software.
|
|
14
|
+
3. **Context-Sized Increments:** Size each task to fit cleanly in a fresh context window (~50-150 lines of focused diff). Small slices keep regressions visible and rollbacks painless.
|
|
15
|
+
4. **Explicit Dependency DAG:** Every task must declare its blocking prerequisites (\`Blocked By: [task-ids]\`). Tasks with zero blockers form the "Ready Frontier".
|
|
16
|
+
5. **Declared Public Seams:** Every task must specify the automated test file or assertion that will prove its completion.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## The Wide-Refactor Exception (Expand-and-Contract)
|
|
21
|
+
|
|
22
|
+
If the change involves a **wide cross-cutting refactor** (e.g. renaming a ubiquitous symbol or schema column) where a single edit affects many files and cannot stay green as a single vertical slice:
|
|
23
|
+
- **Phase A (Expand):** Add the new interface or column alongside the existing one. Both coexist; existing tests remain green.
|
|
24
|
+
- **Phase B (Migrate):** Migrate callers in bounded batches (by package or directory). Each batch is a task blocked by Expand, keeping CI green.
|
|
25
|
+
- **Phase C (Contract):** Once all callers use the new form, remove the old interface/column in a task blocked by all migration batches.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Output Artifact: tasks/plan.md
|
|
30
|
+
|
|
31
|
+
Create directory \`tasks/\` if needed, and write \`tasks/plan.md\`:
|
|
32
|
+
|
|
33
|
+
\`\`\`markdown
|
|
34
|
+
# Implementation Plan: [Feature Name]
|
|
35
|
+
|
|
36
|
+
## Frontier (Ready to Execute)
|
|
37
|
+
- [ ] **Task 1: [Short Title]**
|
|
38
|
+
- **Seam:** \`test/seam.test.ts\`
|
|
39
|
+
- **Scope:** [Vertical slice description]
|
|
40
|
+
- **Acceptance Criteria:** [Verifiable criteria]
|
|
41
|
+
- **Blocked By:** None
|
|
42
|
+
|
|
43
|
+
## Sequence (Blocked)
|
|
44
|
+
- [ ] **Task 2: [Short Title]**
|
|
45
|
+
- **Seam:** \`test/api.test.ts\`
|
|
46
|
+
- **Scope:** [Vertical slice description]
|
|
47
|
+
- **Blocked By:** Task 1
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
Populate the session task tracking using \`todowrite\` matching the plan tasks.
|
|
51
|
+
Prompt the user for confirmation. Once approved, the user can run \`/build\` (or \`/build auto\`).
|
|
52
|
+
`
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export const SHIP_TEMPLATE = `---
|
|
2
|
+
description: Parallel 4-way pre-launch review (Standards, Spec, Security, QA) with GO/NO-GO verdict.
|
|
3
|
+
---
|
|
4
|
+
# Lifecycle Phase 5: Ship
|
|
5
|
+
|
|
6
|
+
Pre-launch gatekeeper and multi-axis review for proposed changes: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
## 1. Diff Evidence Resolution (Include Uncommitted Work)
|
|
9
|
+
|
|
10
|
+
Do NOT assume changes are committed, and do NOT stage or commit user work just to make review convenient.
|
|
11
|
+
Inspect the complete evidence set:
|
|
12
|
+
1. **Working Tree Status:** Run \`git status --short\` to identify modified, staged, and untracked files.
|
|
13
|
+
2. **Uncommitted Changes:** Run \`git diff HEAD\` (captures both staged and unstaged modifications).
|
|
14
|
+
3. **Branch Commits:** If on a feature branch, run \`git diff origin/main...HEAD\` (or appropriate base branch).
|
|
15
|
+
4. **Untracked Files:** Inspect new relevant files using \`git ls-files --others --exclude-standard\`.
|
|
16
|
+
|
|
17
|
+
Assemble this complete diff into a coherent review packet so all subagents review the exact same snapshot.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Parallel 4-Way Subagent Audit
|
|
22
|
+
|
|
23
|
+
Delegate review to the 4 specialized review subagents concurrently using the \`task\` tool. Running reviews in isolated context windows prevents cognitive bias and context dilution.
|
|
24
|
+
|
|
25
|
+
Spawn the four subagents in parallel with the review packet:
|
|
26
|
+
1. **Standards Reviewer (\`standards-reviewer\`):**
|
|
27
|
+
Evaluates the diff against repository conventions, Martin Fowler's code smells (Feature Envy, Primitive Obsession, Shotgun Surgery), and deep module principles. Read-only terminal worker.
|
|
28
|
+
2. **Spec Reviewer (\`spec-reviewer\`):**
|
|
29
|
+
Evaluates the diff strictly against requirements in \`SPEC.md\` (or task brief). Flags missing acceptance criteria, incomplete edge cases, and unrequested scope creep. Read-only terminal worker.
|
|
30
|
+
3. **Security Auditor (\`security-auditor\`):**
|
|
31
|
+
Adversarial audit of diffs for OWASP Top 10 vulnerabilities, credential/secret leaks, improper input sanitization, and authorization bypasses. Read-only terminal worker.
|
|
32
|
+
4. **Test Engineer (\`test-engineer\`):**
|
|
33
|
+
Audits test coverage gaps, assertion quality (Beyoncé Rule, independent oracles), mocking boundaries, and Prove-It verification. Read-only terminal worker.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. Synthesis & Decision Gate
|
|
38
|
+
|
|
39
|
+
Synthesize findings from all subagents into a structured pre-launch report:
|
|
40
|
+
|
|
41
|
+
\`\`\`markdown
|
|
42
|
+
# Pre-Launch Review Summary
|
|
43
|
+
|
|
44
|
+
## 1. Standards & Code Smells: [PASS | WARN | FAIL]
|
|
45
|
+
(Analysis of architectural leverage, idioms, and code smells)
|
|
46
|
+
|
|
47
|
+
## 2. Spec Compliance: [PASS | WARN | FAIL]
|
|
48
|
+
(Verification against acceptance criteria; verification of zero scope creep)
|
|
49
|
+
|
|
50
|
+
## 3. Security & Boundaries: [PASS | WARN | FAIL]
|
|
51
|
+
(OWASP analysis, secret hygiene, input sanitization)
|
|
52
|
+
|
|
53
|
+
## 4. Test Strategy & Coverage: [PASS | WARN | FAIL]
|
|
54
|
+
(Verification rigor, edge cases, mocking boundaries)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
## Final Verdict: [GO / NO-GO]
|
|
58
|
+
- **Blocking Issues:** (Must be resolved before shipping)
|
|
59
|
+
- **Non-Blocking Suggestions:** (Technical debt to track for later)
|
|
60
|
+
- **Rollback Plan:** (Explicit instructions for reverting if production fails)
|
|
61
|
+
\`\`\`
|
|
62
|
+
|
|
63
|
+
**Authorization Boundary:** A GO verdict is an advisory quality gate. It is NOT authorization to commit, push, or deploy without explicit human approval.
|
|
64
|
+
`
|