Skip to content

Commit a8c69f4

Browse files
committed
fix: prevent agents from creating extra files in spec change folders
1 parent a008b60 commit a8c69f4

8 files changed

Lines changed: 35 additions & 9 deletions

File tree

packages/cli/src/core/validate/spec.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { extractDeclaredDesignElementIds } from './shared/ids.js';
1313
import { verifyDesignFile } from './design.js';
1414
import { verifyTasksFile } from './tasks.js';
1515
import { verifyRequirementsFile } from './requirements.js';
16+
import { verifySpecStructure } from './structure.js';
1617

1718
const SKILL_DOCS = {
1819
requirements: 'skills/spec-driven-requirements-writer/SKILL.md',
@@ -31,14 +32,30 @@ interface SpecValidationResult extends ValidationResult {
3132
};
3233
}
3334

34-
function verifyCompleteSpec(slug: string, targetDir: string): SpecValidationResult {
35+
async function verifyCompleteSpec(slug: string, targetDir: string): Promise<SpecValidationResult> {
3536
const errors: ValidationError[] = [];
3637
const requirementsErrors: string[] = [];
3738
const designErrors: string[] = [];
3839
const tasksErrors: string[] = [];
3940

4041
const specDir = path.join(targetDir, '.specs', 'changes', slug);
4142

43+
const structureResult = await verifySpecStructure(slug, targetDir);
44+
if (!structureResult.valid) {
45+
for (const err of structureResult.errors) {
46+
errors.push(err);
47+
}
48+
}
49+
50+
if (structureResult.unexpectedFiles.length > 0) {
51+
errors.push({
52+
errorType: 'Structure Error',
53+
context: `Unexpected files found: ${structureResult.unexpectedFiles.join(', ')}`,
54+
message: `Unexpected files found`,
55+
suggestedFix: 'Only requirements.md, design.md, and tasks.md are allowed. Remove or rename extra files'
56+
});
57+
}
58+
4259
let requirementsContent = '';
4360
let designContent = '';
4461
let tasksContent = '';
@@ -156,7 +173,7 @@ export function createSpecCommand(): Command {
156173
.option('--target-dir <path>', 'Project root directory', process.cwd())
157174
.option('--format <text|json>', 'Output format (text or json)', 'text')
158175
.action(async (slug: string, opts: { targetDir: string; format: string }) => {
159-
const result = verifyCompleteSpec(slug, opts.targetDir);
176+
const result = await verifyCompleteSpec(slug, opts.targetDir);
160177

161178
if (opts.format === 'json') {
162179
console.log(formatValidationResult(result, 'json'));

packages/cli/src/core/validate/structure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface StructureValidationResult extends ValidationResult {
1919
unexpectedFiles: string[];
2020
}
2121

22-
async function verifySpecStructure(slug: string, targetDir: string): Promise<StructureValidationResult> {
22+
export async function verifySpecStructure(slug: string, targetDir: string): Promise<StructureValidationResult> {
2323
const errors: Array<{ line?: number; errorType: string; context?: string; message: string; suggestedFix?: string }> = [];
2424
const warnings: Array<{ line?: number; message: string }> = [];
2525
const specDir = path.join(targetDir, '.specs', 'changes', slug);

packages/cli/templates/universal/agents/spec-driven.agent.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ You MUST enforce this lifecycle exactly:
1616
- Never skip phases, even if the user asks to implement immediately.
1717
- If there is no approved `.specs/changes/<slug>/requirements.md`, always start with requirements.
1818
- Before Phase 4 is explicitly approved by the human, do not write implementation code.
19-
- Before Phase 4 approval, only write files under `.specs/changes/<slug>/`.
19+
- Before Phase 4 approval, only write the three spec files under `.specs/changes/<slug>/`: requirements.md, design.md, tasks.md. No other files are permitted in this directory.
2020
- Every phase transition requires explicit human approval.
2121
- For requirements, design, and tasks, always validate and write the artifact first, then ask whether to proceed.
2222

packages/cli/templates/universal/skills/agent-work-auditor/references/migration/phase-0-inventory.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,4 @@ The inventory must satisfy:
8585
2. **Component registry complete** — All significant modules catalogued
8686
3. **Interfaces documented** — All external APIs captured
8787
4. **Side effects logged** — All observable side effects recorded
88-
5. **Assumptions documented** — No critical assumption left unstated
89-
90-
## Output Location
91-
92-
Inventory is saved to `.specs/changes/{slug}/codebase-inventory.md`
88+
5. **Assumptions documented** — No critical assumption left unstated

packages/cli/templates/universal/skills/spec-driven-requirements-writer/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,7 @@ This ensures the requirements document meets quality standards across:
370370
- **Functionality**: Complete requirements, clear acceptance criteria, no gaps
371371

372372
The quality-grading skill will auto-fix issues scoring below 4 and provide actionable suggestions for remaining gaps.
373+
374+
## Things To Avoid
375+
376+
- Creating additional files in `.specs/changes/<slug>/`. Only write requirements.md for this phase.

packages/cli/templates/universal/skills/spec-driven-task-decomposer/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,3 +405,7 @@ Query: workflow
405405
```
406406

407407
This ensures the task breakdown aligns with team processes, testing rules, and naming conventions.
408+
409+
## Things To Avoid
410+
411+
- Creating additional files in `.specs/changes/<slug>/`. Only write tasks.md for this phase.

packages/cli/templates/universal/skills/spec-driven-task-implementer/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ If work resumes after interruption:
234234
- marking tasks complete without verification
235235
- batching multiple task status updates after the fact
236236
- introducing secrets or sensitive data into the repository
237+
- creating additional files in `.specs/changes/<slug>/`. Only write to tasks.md for status updates.
237238

238239
## Quality Bar (Self-Check)
239240

packages/cli/templates/universal/skills/spec-driven-technical-designer/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,3 +501,7 @@ Query: architecture
501501
```
502502

503503
This ensures the new design aligns with existing tech stack choices, design patterns, and tooling decisions.
504+
505+
## Things To Avoid
506+
507+
- Creating additional files in `.specs/changes/<slug>/`. Only write design.md for this phase.

0 commit comments

Comments
 (0)