workspace-maxxing 0.1.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/.agents/skills/workspace-maxxing/.workspace-templates/CONTEXT.md +44 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/SYSTEM.md +44 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/anti-patterns.md +16 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/iron-laws.md +26 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/references/reporting-format.md +52 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/benchmark.ts +171 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/dispatch.ts +473 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/generate-tests.ts +158 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/install-tool.ts +82 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/iterate.ts +265 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/orchestrator.ts +539 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/scaffold.ts +282 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/validate.ts +452 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/architecture/SKILL.md +95 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/fixer/SKILL.md +109 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/iteration/SKILL.md +89 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/research/SKILL.md +94 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/testing/SKILL.md +89 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/tooling/SKILL.md +87 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/validation/SKILL.md +103 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/skills/worker/SKILL.md +79 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
- package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/README.md +14 -0
- package/.agents/skills/workspace-maxxing/SKILL.md +312 -0
- package/.agents/skills/workspace-maxxing/scripts/benchmark.ts +171 -0
- package/.agents/skills/workspace-maxxing/scripts/dispatch.ts +473 -0
- package/.agents/skills/workspace-maxxing/scripts/generate-tests.ts +158 -0
- package/.agents/skills/workspace-maxxing/scripts/install-tool.ts +82 -0
- package/.agents/skills/workspace-maxxing/scripts/iterate.ts +265 -0
- package/.agents/skills/workspace-maxxing/scripts/orchestrator.ts +539 -0
- package/.agents/skills/workspace-maxxing/scripts/scaffold.ts +282 -0
- package/.agents/skills/workspace-maxxing/scripts/validate.ts +452 -0
- package/README.md +144 -0
- package/dist/agent-creator.d.ts +9 -0
- package/dist/agent-creator.d.ts.map +1 -0
- package/dist/agent-creator.js +199 -0
- package/dist/agent-creator.js.map +1 -0
- package/dist/agent-iterator.d.ts +38 -0
- package/dist/agent-iterator.d.ts.map +1 -0
- package/dist/agent-iterator.js +327 -0
- package/dist/agent-iterator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +18 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +117 -0
- package/dist/install.js.map +1 -0
- package/dist/platforms/claude.d.ts +7 -0
- package/dist/platforms/claude.d.ts.map +1 -0
- package/dist/platforms/claude.js +70 -0
- package/dist/platforms/claude.js.map +1 -0
- package/dist/platforms/copilot.d.ts +7 -0
- package/dist/platforms/copilot.d.ts.map +1 -0
- package/dist/platforms/copilot.js +75 -0
- package/dist/platforms/copilot.js.map +1 -0
- package/dist/platforms/gemini.d.ts +7 -0
- package/dist/platforms/gemini.d.ts.map +1 -0
- package/dist/platforms/gemini.js +81 -0
- package/dist/platforms/gemini.js.map +1 -0
- package/dist/platforms/index.d.ts +8 -0
- package/dist/platforms/index.d.ts.map +1 -0
- package/dist/platforms/index.js +41 -0
- package/dist/platforms/index.js.map +1 -0
- package/dist/platforms/opencode.d.ts +7 -0
- package/dist/platforms/opencode.d.ts.map +1 -0
- package/dist/platforms/opencode.js +70 -0
- package/dist/platforms/opencode.js.map +1 -0
- package/dist/scripts/benchmark.d.ts +20 -0
- package/dist/scripts/benchmark.d.ts.map +1 -0
- package/dist/scripts/benchmark.js +170 -0
- package/dist/scripts/benchmark.js.map +1 -0
- package/dist/scripts/dispatch.d.ts +32 -0
- package/dist/scripts/dispatch.d.ts.map +1 -0
- package/dist/scripts/dispatch.js +386 -0
- package/dist/scripts/dispatch.js.map +1 -0
- package/dist/scripts/generate-tests.d.ts +11 -0
- package/dist/scripts/generate-tests.d.ts.map +1 -0
- package/dist/scripts/generate-tests.js +118 -0
- package/dist/scripts/generate-tests.js.map +1 -0
- package/dist/scripts/install-tool.d.ts +8 -0
- package/dist/scripts/install-tool.d.ts.map +1 -0
- package/dist/scripts/install-tool.js +98 -0
- package/dist/scripts/install-tool.js.map +1 -0
- package/dist/scripts/iterate.d.ts +44 -0
- package/dist/scripts/iterate.d.ts.map +1 -0
- package/dist/scripts/iterate.js +260 -0
- package/dist/scripts/iterate.js.map +1 -0
- package/dist/scripts/orchestrator.d.ts +40 -0
- package/dist/scripts/orchestrator.d.ts.map +1 -0
- package/dist/scripts/orchestrator.js +378 -0
- package/dist/scripts/orchestrator.js.map +1 -0
- package/dist/scripts/scaffold.d.ts +8 -0
- package/dist/scripts/scaffold.d.ts.map +1 -0
- package/dist/scripts/scaffold.js +279 -0
- package/dist/scripts/scaffold.js.map +1 -0
- package/dist/scripts/validate.d.ts +11 -0
- package/dist/scripts/validate.d.ts.map +1 -0
- package/dist/scripts/validate.js +472 -0
- package/dist/scripts/validate.js.map +1 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-iteration-plan.md +1123 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-iteration-sub-agent-batches.md +1923 -0
- package/docs/superpowers/plans/2026-04-07-autonomous-workflow-sub-skill-plan.md +1505 -0
- package/docs/superpowers/plans/2026-04-07-benchmarking-multi-agent-plan.md +854 -0
- package/docs/superpowers/plans/2026-04-07-workspace-builder-logic-plan.md +1426 -0
- package/docs/superpowers/plans/2026-04-07-workspace-maxxing-plan.md +1299 -0
- package/docs/superpowers/plans/2026-04-08-session-294c-subagent-invocation-plan.md +320 -0
- package/docs/superpowers/plans/2026-04-08-workflow-prompt-hardening-plan.md +1025 -0
- package/docs/superpowers/plans/2026-04-12-workspace-agent-creation-plan.md +992 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-iteration-design.md +214 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-iteration-sub-agent-batches-design.md +188 -0
- package/docs/superpowers/specs/2026-04-07-autonomous-workflow-sub-skill-design.md +137 -0
- package/docs/superpowers/specs/2026-04-07-benchmarking-multi-agent-design.md +105 -0
- package/docs/superpowers/specs/2026-04-07-workspace-builder-logic-design.md +179 -0
- package/docs/superpowers/specs/2026-04-07-workspace-maxxing-design.md +227 -0
- package/docs/superpowers/specs/2026-04-08-session-294c-subagent-invocation-design.md +265 -0
- package/docs/superpowers/specs/2026-04-08-workflow-prompt-hardening-design.md +146 -0
- package/docs/superpowers/specs/2026-04-12-workspace-agent-creation-design.md +239 -0
- package/jest.config.js +8 -0
- package/package.json +32 -0
- package/src/agent-creator.ts +180 -0
- package/src/agent-iterator.ts +397 -0
- package/src/index.ts +189 -0
- package/src/install.ts +105 -0
- package/src/platforms/claude.ts +40 -0
- package/src/platforms/copilot.ts +50 -0
- package/src/platforms/gemini.ts +55 -0
- package/src/platforms/index.ts +45 -0
- package/src/platforms/opencode.ts +41 -0
- package/src/scripts/benchmark.ts +171 -0
- package/src/scripts/dispatch.ts +473 -0
- package/src/scripts/generate-tests.ts +112 -0
- package/src/scripts/install-tool.ts +82 -0
- package/src/scripts/iterate.ts +271 -0
- package/src/scripts/orchestrator.ts +539 -0
- package/src/scripts/scaffold.ts +282 -0
- package/src/scripts/validate.ts +516 -0
- package/templates/.workspace-templates/CONTEXT.md +44 -0
- package/templates/.workspace-templates/SYSTEM.md +44 -0
- package/templates/.workspace-templates/references/anti-patterns.md +16 -0
- package/templates/.workspace-templates/references/iron-laws.md +26 -0
- package/templates/.workspace-templates/references/reporting-format.md +52 -0
- package/templates/.workspace-templates/scripts/benchmark.ts +171 -0
- package/templates/.workspace-templates/scripts/dispatch.ts +473 -0
- package/templates/.workspace-templates/scripts/generate-tests.ts +158 -0
- package/templates/.workspace-templates/scripts/install-tool.ts +82 -0
- package/templates/.workspace-templates/scripts/iterate.ts +265 -0
- package/templates/.workspace-templates/scripts/orchestrator.ts +539 -0
- package/templates/.workspace-templates/scripts/scaffold.ts +282 -0
- package/templates/.workspace-templates/scripts/validate.ts +452 -0
- package/templates/.workspace-templates/skills/architecture/SKILL.md +95 -0
- package/templates/.workspace-templates/skills/fixer/SKILL.md +109 -0
- package/templates/.workspace-templates/skills/iteration/SKILL.md +89 -0
- package/templates/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
- package/templates/.workspace-templates/skills/research/SKILL.md +94 -0
- package/templates/.workspace-templates/skills/testing/SKILL.md +89 -0
- package/templates/.workspace-templates/skills/tooling/SKILL.md +87 -0
- package/templates/.workspace-templates/skills/validation/SKILL.md +103 -0
- package/templates/.workspace-templates/skills/worker/SKILL.md +79 -0
- package/templates/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
- package/templates/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
- package/templates/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
- package/templates/.workspace-templates/workspace/README.md +14 -0
- package/templates/SKILL.md +347 -0
- package/tests/benchmark.test.ts +158 -0
- package/tests/cli.test.ts +109 -0
- package/tests/dispatch-parallel.test.ts +124 -0
- package/tests/dispatch.test.ts +218 -0
- package/tests/fixer-skill.test.ts +203 -0
- package/tests/generate-tests.test.ts +101 -0
- package/tests/install-tool.test.ts +141 -0
- package/tests/install.test.ts +144 -0
- package/tests/integration.test.ts +324 -0
- package/tests/iterate.test.ts +219 -0
- package/tests/orchestrator.test.ts +710 -0
- package/tests/scaffold.test.ts +238 -0
- package/tests/templates-enhanced.test.ts +208 -0
- package/tests/templates.test.ts +219 -0
- package/tests/validate.test.ts +421 -0
- package/tests/validation-enhanced.test.ts +303 -0
- package/tests/worker-skill.test.ts +88 -0
- package/tsconfig.json +19 -0
- package/workspace/00-meta/CONTEXT.md +3 -0
- package/workspace/00-meta/execution-log.md +17 -0
- package/workspace/00-meta/tools.md +11 -0
- package/workspace/01-input/CONTEXT.md +27 -0
- package/workspace/CONTEXT.md +35 -0
- package/workspace/README.md +14 -0
- package/workspace/SYSTEM.md +36 -0
- package/workspace-maxxing-0.1.0.tgz +0 -0
|
@@ -0,0 +1,1025 @@
|
|
|
1
|
+
# Workflow Prompt Hardening Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Harden scaffolded `SYSTEM.md` and `CONTEXT.md` generation so agents reliably follow stage workflow, and enforce the same contracts with stricter validation checks.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Keep the existing scaffold-and-validate architecture and upgrade it with explicit section contracts and workflow-semantic checks. Generation remains in `scaffold.ts`, enforcement remains in `validate.ts`, and templates are aligned to the same contract. Implementation follows strict TDD: failing tests first, minimal implementation, then regression verification.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Node.js built-ins (`fs`, `path`), Jest.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Responsibility Map
|
|
14
|
+
|
|
15
|
+
- `src/scripts/scaffold.ts`: Generate robust root and stage prompts with explicit workflow contracts.
|
|
16
|
+
- `src/scripts/validate.ts`: Enforce required prompt sections and stage workflow consistency rules.
|
|
17
|
+
- `templates/.workspace-templates/SYSTEM.md`: Canonical root system prompt template.
|
|
18
|
+
- `templates/.workspace-templates/CONTEXT.md`: Canonical root router prompt template.
|
|
19
|
+
- `templates/.workspace-templates/workspace/01-input/CONTEXT.md`: Canonical stage 1 prompt contract.
|
|
20
|
+
- `templates/.workspace-templates/workspace/02-process/CONTEXT.md`: Canonical stage 2 prompt contract.
|
|
21
|
+
- `templates/.workspace-templates/workspace/03-output/CONTEXT.md`: Canonical stage 3 prompt contract.
|
|
22
|
+
- `tests/scaffold.test.ts`: TDD coverage for generated prompt contracts.
|
|
23
|
+
- `tests/validate.test.ts`: TDD coverage for strict structure and workflow checks.
|
|
24
|
+
- `tests/templates.test.ts`: Ensure shipped templates include required robust prompt sections.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
### Task 1: Harden Root Prompt Generation in Scaffold
|
|
29
|
+
|
|
30
|
+
**Files:**
|
|
31
|
+
- Modify: `tests/scaffold.test.ts`
|
|
32
|
+
- Modify: `src/scripts/scaffold.ts`
|
|
33
|
+
|
|
34
|
+
- [ ] **Step 1: Write failing tests for robust root SYSTEM and CONTEXT generation**
|
|
35
|
+
|
|
36
|
+
Add these tests to `tests/scaffold.test.ts`:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
it('creates robust SYSTEM.md sections for workflow-following prompts', () => {
|
|
40
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
41
|
+
scaffoldWorkspace({
|
|
42
|
+
name: 'research',
|
|
43
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
44
|
+
output: outputDir,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const systemMd = fs.readFileSync(path.join(outputDir, 'SYSTEM.md'), 'utf-8');
|
|
48
|
+
expect(systemMd).toContain('## Role');
|
|
49
|
+
expect(systemMd).toContain('## Folder Map');
|
|
50
|
+
expect(systemMd).toContain('## Workflow Rules');
|
|
51
|
+
expect(systemMd).toContain('## Stage Boundaries');
|
|
52
|
+
expect(systemMd).toContain('## Tooling Policy');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('creates robust root CONTEXT.md routing and loading order', () => {
|
|
56
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
57
|
+
scaffoldWorkspace({
|
|
58
|
+
name: 'research',
|
|
59
|
+
stages: ['01-research', '02-analysis', '03-report'],
|
|
60
|
+
output: outputDir,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const contextMd = fs.readFileSync(path.join(outputDir, 'CONTEXT.md'), 'utf-8');
|
|
64
|
+
expect(contextMd).toContain('## How to Use This File');
|
|
65
|
+
expect(contextMd).toContain('## Task Routing');
|
|
66
|
+
expect(contextMd).toContain('## Loading Order');
|
|
67
|
+
expect(contextMd).toContain('## Stage Handoff Routing');
|
|
68
|
+
expect(contextMd).toContain('## Escalation');
|
|
69
|
+
|
|
70
|
+
expect(contextMd).toContain('01-research/CONTEXT.md');
|
|
71
|
+
expect(contextMd).toContain('02-analysis/CONTEXT.md');
|
|
72
|
+
expect(contextMd).toContain('03-report/CONTEXT.md');
|
|
73
|
+
expect(contextMd).toContain('SYSTEM.md');
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- [ ] **Step 2: Run tests to verify they fail**
|
|
78
|
+
|
|
79
|
+
Run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx jest tests/scaffold.test.ts -t "robust" -v
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Expected: FAIL with missing headings such as `## Workflow Rules` and `## How to Use This File`.
|
|
86
|
+
|
|
87
|
+
- [ ] **Step 3: Implement minimal root prompt generation changes**
|
|
88
|
+
|
|
89
|
+
Update `generateSystemMd` and `generateContextMd` in `src/scripts/scaffold.ts`:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
function generateSystemMd(name: string, stages: string[]): string {
|
|
93
|
+
const folderRows = stages
|
|
94
|
+
.map((stage, index) => `| ${index + 1} | \`${stage}/\` | ${stageDescription(stage)} |`)
|
|
95
|
+
.join('\n');
|
|
96
|
+
|
|
97
|
+
return `# ${name} — System Prompt
|
|
98
|
+
|
|
99
|
+
## Role
|
|
100
|
+
You are an AI assistant operating inside the ${name} workspace. Follow stage boundaries and route tasks through stage-specific CONTEXT files.
|
|
101
|
+
|
|
102
|
+
## Folder Map
|
|
103
|
+
|
|
104
|
+
| Stage | Folder | Purpose |
|
|
105
|
+
|------:|--------|---------|
|
|
106
|
+
${folderRows}
|
|
107
|
+
| meta | \`00-meta/\` | Workspace configuration, tool inventory, and session notes |
|
|
108
|
+
|
|
109
|
+
## Workflow Rules
|
|
110
|
+
1. Read \`SYSTEM.md\` first, then root \`CONTEXT.md\`.
|
|
111
|
+
2. Load only one stage \`CONTEXT.md\` at a time unless handoff explicitly requires another stage.
|
|
112
|
+
3. Keep information canonical; do not duplicate facts across files.
|
|
113
|
+
4. Maintain one-way stage dependencies from earlier stage numbers to later stage numbers.
|
|
114
|
+
|
|
115
|
+
## Stage Boundaries
|
|
116
|
+
- Each numbered folder is an execution stage.
|
|
117
|
+
- A stage may consume upstream outputs but must not redefine upstream facts.
|
|
118
|
+
- Cross-stage jumps require explicit routing through root \`CONTEXT.md\`.
|
|
119
|
+
|
|
120
|
+
## Tooling Policy
|
|
121
|
+
- Check \`00-meta/tools.md\` before proposing tool installation.
|
|
122
|
+
- Document approved tooling changes in \`00-meta/tools.md\`.
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function generateContextMd(name: string, stages: string[]): string {
|
|
127
|
+
const routingRows = stages
|
|
128
|
+
.map((stage) => `| Work in ${stage} tasks | \`${stage}/CONTEXT.md\` | Stage contract and required outputs |`)
|
|
129
|
+
.join('\n');
|
|
130
|
+
|
|
131
|
+
const handoffs = stages
|
|
132
|
+
.map((stage, index) => {
|
|
133
|
+
const nextStage = stages[index + 1];
|
|
134
|
+
return nextStage
|
|
135
|
+
? `- \`${stage}\` -> \`${nextStage}\` when completion criteria are met`
|
|
136
|
+
: `- \`${stage}\` -> deliver final output and close loop`;
|
|
137
|
+
})
|
|
138
|
+
.join('\n');
|
|
139
|
+
|
|
140
|
+
return `# ${name} — Context Router
|
|
141
|
+
|
|
142
|
+
## How to Use This File
|
|
143
|
+
Use this file to route each task to the smallest required context scope.
|
|
144
|
+
|
|
145
|
+
## Task Routing
|
|
146
|
+
|
|
147
|
+
| When you need to... | Load | Why |
|
|
148
|
+
|---------------------|------|-----|
|
|
149
|
+
| Understand workspace constraints | \`SYSTEM.md\` | Global rules and stage boundaries |
|
|
150
|
+
${routingRows}
|
|
151
|
+
| Check available tools | \`00-meta/tools.md\` | Tool inventory and approval status |
|
|
152
|
+
|
|
153
|
+
## Loading Order
|
|
154
|
+
1. \`SYSTEM.md\` (always)
|
|
155
|
+
2. This root \`CONTEXT.md\`
|
|
156
|
+
3. One relevant stage \`CONTEXT.md\`
|
|
157
|
+
4. Only the task files needed for that stage
|
|
158
|
+
|
|
159
|
+
## Stage Handoff Routing
|
|
160
|
+
${handoffs}
|
|
161
|
+
|
|
162
|
+
## Escalation
|
|
163
|
+
Escalate when required sections are missing, dependencies are contradictory, or no valid stage route can satisfy the task.
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- [ ] **Step 4: Run tests to verify pass**
|
|
169
|
+
|
|
170
|
+
Run:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npx jest tests/scaffold.test.ts -t "robust" -v
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Expected: PASS.
|
|
177
|
+
|
|
178
|
+
- [ ] **Step 5: Commit**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
git add tests/scaffold.test.ts src/scripts/scaffold.ts
|
|
182
|
+
git commit -m "feat(scaffold): generate robust root workflow prompts"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### Task 2: Harden Stage CONTEXT Generation in Scaffold
|
|
188
|
+
|
|
189
|
+
**Files:**
|
|
190
|
+
- Modify: `tests/scaffold.test.ts`
|
|
191
|
+
- Modify: `src/scripts/scaffold.ts`
|
|
192
|
+
|
|
193
|
+
- [ ] **Step 1: Write failing tests for stage section contracts and handoff details**
|
|
194
|
+
|
|
195
|
+
Add this test to `tests/scaffold.test.ts`:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
it('creates stage CONTEXT.md files with completion and handoff contracts', () => {
|
|
199
|
+
const outputDir = path.join(tempDir, 'workspace');
|
|
200
|
+
const stages = ['01-research', '02-analysis', '03-report'];
|
|
201
|
+
|
|
202
|
+
scaffoldWorkspace({
|
|
203
|
+
name: 'research',
|
|
204
|
+
stages,
|
|
205
|
+
output: outputDir,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
for (let i = 0; i < stages.length; i++) {
|
|
209
|
+
const stage = stages[i];
|
|
210
|
+
const nextStage = stages[i + 1];
|
|
211
|
+
const stageContext = fs.readFileSync(path.join(outputDir, stage, 'CONTEXT.md'), 'utf-8');
|
|
212
|
+
|
|
213
|
+
expect(stageContext).toContain('## Purpose');
|
|
214
|
+
expect(stageContext).toContain('## Inputs');
|
|
215
|
+
expect(stageContext).toContain('## Outputs');
|
|
216
|
+
expect(stageContext).toContain('## Dependencies');
|
|
217
|
+
expect(stageContext).toContain('## Completion Criteria');
|
|
218
|
+
expect(stageContext).toContain('## Handoff');
|
|
219
|
+
|
|
220
|
+
if (nextStage) {
|
|
221
|
+
expect(stageContext).toContain(nextStage);
|
|
222
|
+
} else {
|
|
223
|
+
expect(stageContext.toLowerCase()).toContain('final output');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- [ ] **Step 2: Run test to verify fail**
|
|
230
|
+
|
|
231
|
+
Run:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npx jest tests/scaffold.test.ts -t "completion and handoff" -v
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Expected: FAIL because generated stage contexts do not contain `## Completion Criteria` and `## Handoff`.
|
|
238
|
+
|
|
239
|
+
- [ ] **Step 3: Implement stage generation changes**
|
|
240
|
+
|
|
241
|
+
Update stage loop and `generateStageContextMd` in `src/scripts/scaffold.ts`:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
for (const stage of stages) {
|
|
245
|
+
const stageDir = path.join(outputDir, stage);
|
|
246
|
+
fs.mkdirSync(stageDir, { recursive: true });
|
|
247
|
+
fs.writeFileSync(
|
|
248
|
+
path.join(stageDir, 'CONTEXT.md'),
|
|
249
|
+
generateStageContextMd(name, stage, stages),
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function generateStageContextMd(name: string, stage: string, stages: string[]): string {
|
|
254
|
+
const stageIndex = stages.indexOf(stage);
|
|
255
|
+
const previousStage = stageIndex > 0 ? stages[stageIndex - 1] : undefined;
|
|
256
|
+
const nextStage = stageIndex >= 0 && stageIndex < stages.length - 1
|
|
257
|
+
? stages[stageIndex + 1]
|
|
258
|
+
: undefined;
|
|
259
|
+
|
|
260
|
+
const dependencyLine = previousStage
|
|
261
|
+
? `- ${previousStage}`
|
|
262
|
+
: '- None (entry stage)';
|
|
263
|
+
|
|
264
|
+
const handoffLine = nextStage
|
|
265
|
+
? `- After completion, hand off outputs to ${nextStage}`
|
|
266
|
+
: '- This is the terminal stage. Package and deliver final output.';
|
|
267
|
+
|
|
268
|
+
return `# ${stage} — Context
|
|
269
|
+
|
|
270
|
+
## Purpose
|
|
271
|
+
This folder executes the ${stage} stage of the ${name} workflow.
|
|
272
|
+
|
|
273
|
+
## Inputs
|
|
274
|
+
- Required data artifacts for ${stage}
|
|
275
|
+
- Upstream context from previous stage when applicable
|
|
276
|
+
|
|
277
|
+
## Outputs
|
|
278
|
+
- Stage-specific deliverables for downstream consumption
|
|
279
|
+
- Updated artifacts needed by the next stage
|
|
280
|
+
|
|
281
|
+
## Dependencies
|
|
282
|
+
${dependencyLine}
|
|
283
|
+
|
|
284
|
+
## Completion Criteria
|
|
285
|
+
- Required outputs are produced and non-empty
|
|
286
|
+
- Outputs conform to stage purpose and expected format
|
|
287
|
+
- Handoff notes are updated for downstream stage
|
|
288
|
+
|
|
289
|
+
## Handoff
|
|
290
|
+
${handoffLine}
|
|
291
|
+
`;
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
- [ ] **Step 4: Run test to verify pass**
|
|
296
|
+
|
|
297
|
+
Run:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
npx jest tests/scaffold.test.ts -t "completion and handoff" -v
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Expected: PASS.
|
|
304
|
+
|
|
305
|
+
- [ ] **Step 5: Commit**
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
git add tests/scaffold.test.ts src/scripts/scaffold.ts
|
|
309
|
+
git commit -m "feat(scaffold): add stage completion and handoff contracts"
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### Task 3: Align Shipped Template Prompt Files and Template Tests
|
|
315
|
+
|
|
316
|
+
**Files:**
|
|
317
|
+
- Modify: `tests/templates.test.ts`
|
|
318
|
+
- Modify: `templates/.workspace-templates/SYSTEM.md`
|
|
319
|
+
- Modify: `templates/.workspace-templates/CONTEXT.md`
|
|
320
|
+
- Modify: `templates/.workspace-templates/workspace/01-input/CONTEXT.md`
|
|
321
|
+
- Modify: `templates/.workspace-templates/workspace/02-process/CONTEXT.md`
|
|
322
|
+
- Modify: `templates/.workspace-templates/workspace/03-output/CONTEXT.md`
|
|
323
|
+
|
|
324
|
+
- [ ] **Step 1: Write failing template tests for robust section contracts**
|
|
325
|
+
|
|
326
|
+
Add tests to `tests/templates.test.ts`:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
it('SYSTEM.md includes robust workflow sections', () => {
|
|
330
|
+
const systemPath = path.join(templatesDir, '.workspace-templates', 'SYSTEM.md');
|
|
331
|
+
const content = fs.readFileSync(systemPath, 'utf-8');
|
|
332
|
+
|
|
333
|
+
expect(content).toContain('## Role');
|
|
334
|
+
expect(content).toContain('## Folder Map');
|
|
335
|
+
expect(content).toContain('## Workflow Rules');
|
|
336
|
+
expect(content).toContain('## Stage Boundaries');
|
|
337
|
+
expect(content).toContain('## Tooling Policy');
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('root CONTEXT.md includes routing, loading order, and handoff routing', () => {
|
|
341
|
+
const contextPath = path.join(templatesDir, '.workspace-templates', 'CONTEXT.md');
|
|
342
|
+
const content = fs.readFileSync(contextPath, 'utf-8');
|
|
343
|
+
|
|
344
|
+
expect(content).toContain('## How to Use This File');
|
|
345
|
+
expect(content).toContain('## Task Routing');
|
|
346
|
+
expect(content).toContain('## Loading Order');
|
|
347
|
+
expect(content).toContain('## Stage Handoff Routing');
|
|
348
|
+
expect(content).toContain('## Escalation');
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('stage context templates include completion and handoff sections', () => {
|
|
352
|
+
const stageFiles = [
|
|
353
|
+
'.workspace-templates/workspace/01-input/CONTEXT.md',
|
|
354
|
+
'.workspace-templates/workspace/02-process/CONTEXT.md',
|
|
355
|
+
'.workspace-templates/workspace/03-output/CONTEXT.md',
|
|
356
|
+
];
|
|
357
|
+
|
|
358
|
+
for (const file of stageFiles) {
|
|
359
|
+
const content = fs.readFileSync(path.join(templatesDir, file), 'utf-8');
|
|
360
|
+
expect(content).toContain('## Purpose');
|
|
361
|
+
expect(content).toContain('## Inputs');
|
|
362
|
+
expect(content).toContain('## Outputs');
|
|
363
|
+
expect(content).toContain('## Dependencies');
|
|
364
|
+
expect(content).toContain('## Completion Criteria');
|
|
365
|
+
expect(content).toContain('## Handoff');
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
- [ ] **Step 2: Run tests to verify fail**
|
|
371
|
+
|
|
372
|
+
Run:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
npx jest tests/templates.test.ts -t "robust|handoff" -v
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Expected: FAIL due missing robust sections in template files.
|
|
379
|
+
|
|
380
|
+
- [ ] **Step 3: Update template prompt files to match contract**
|
|
381
|
+
|
|
382
|
+
Replace `templates/.workspace-templates/SYSTEM.md` with:
|
|
383
|
+
|
|
384
|
+
```markdown
|
|
385
|
+
# System — Workspace Root
|
|
386
|
+
|
|
387
|
+
## Role
|
|
388
|
+
You are an AI assistant operating inside this workspace. Follow stage contracts, route tasks through stage contexts, and keep information canonical.
|
|
389
|
+
|
|
390
|
+
## Folder Map
|
|
391
|
+
|
|
392
|
+
| Folder | Purpose |
|
|
393
|
+
|--------|---------|
|
|
394
|
+
| 00-meta/ | Workspace configuration, tool inventory, session notes |
|
|
395
|
+
| 01-input/ | Source materials, intake, and validation |
|
|
396
|
+
| 02-process/ | Analysis, transformation, and drafting |
|
|
397
|
+
| 03-output/ | Final deliverables and publication artifacts |
|
|
398
|
+
|
|
399
|
+
## Workflow Rules
|
|
400
|
+
1. Read this file first every session.
|
|
401
|
+
2. Read root `CONTEXT.md` before loading stage files.
|
|
402
|
+
3. Load only the stage context and task files required for the current step.
|
|
403
|
+
4. Keep one canonical source for each fact; do not duplicate content across stages.
|
|
404
|
+
|
|
405
|
+
## Stage Boundaries
|
|
406
|
+
- Execute stages in order unless explicit handoff says otherwise.
|
|
407
|
+
- One-way dependencies only: upstream -> downstream.
|
|
408
|
+
- Downstream stages may reference upstream outputs, never reverse.
|
|
409
|
+
|
|
410
|
+
## Tooling Policy
|
|
411
|
+
- Tool inventory is tracked in `00-meta/tools.md`.
|
|
412
|
+
- Check inventory before proposing installs.
|
|
413
|
+
- Record approved tool changes in `00-meta/tools.md`.
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Replace `templates/.workspace-templates/CONTEXT.md` with:
|
|
417
|
+
|
|
418
|
+
```markdown
|
|
419
|
+
# Routing Table
|
|
420
|
+
|
|
421
|
+
## How to Use This File
|
|
422
|
+
Map each task to the smallest required context and avoid loading unrelated files.
|
|
423
|
+
|
|
424
|
+
## Task Routing
|
|
425
|
+
|
|
426
|
+
| When you need to... | Go to | Load |
|
|
427
|
+
|---------------------|-------|------|
|
|
428
|
+
| Understand workspace constraints | SYSTEM.md | Always loaded first |
|
|
429
|
+
| Gather or validate inputs | 01-input/CONTEXT.md | Input stage contract |
|
|
430
|
+
| Analyze, process, or draft | 02-process/CONTEXT.md | Processing stage contract |
|
|
431
|
+
| Finalize and deliver outputs | 03-output/CONTEXT.md | Output stage contract |
|
|
432
|
+
| Check available tools | 00-meta/tools.md | Tool inventory |
|
|
433
|
+
|
|
434
|
+
## Loading Order
|
|
435
|
+
1. SYSTEM.md (always)
|
|
436
|
+
2. This root CONTEXT.md
|
|
437
|
+
3. One relevant stage CONTEXT.md
|
|
438
|
+
4. Only the task files needed for that stage
|
|
439
|
+
|
|
440
|
+
## Stage Handoff Routing
|
|
441
|
+
- 01-input -> 02-process when input completion criteria are met
|
|
442
|
+
- 02-process -> 03-output when processing completion criteria are met
|
|
443
|
+
- 03-output -> delivery and closure
|
|
444
|
+
|
|
445
|
+
## Escalation
|
|
446
|
+
Escalate when required sections are missing, routing is ambiguous, or dependencies conflict with stage order.
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Replace `templates/.workspace-templates/workspace/01-input/CONTEXT.md` with:
|
|
450
|
+
|
|
451
|
+
```markdown
|
|
452
|
+
# 01-input CONTEXT.md
|
|
453
|
+
|
|
454
|
+
## Purpose
|
|
455
|
+
Collect, validate, and normalize workflow inputs.
|
|
456
|
+
|
|
457
|
+
## Inputs
|
|
458
|
+
- Raw user input and source artifacts
|
|
459
|
+
- Intake constraints and acceptance boundaries
|
|
460
|
+
|
|
461
|
+
## Outputs
|
|
462
|
+
- Validated input package ready for processing
|
|
463
|
+
- Input assumptions and constraints summary
|
|
464
|
+
|
|
465
|
+
## Dependencies
|
|
466
|
+
- None (entry stage)
|
|
467
|
+
|
|
468
|
+
## Completion Criteria
|
|
469
|
+
- Inputs are validated and normalized
|
|
470
|
+
- Required fields are present
|
|
471
|
+
- Handoff package is complete
|
|
472
|
+
|
|
473
|
+
## Handoff
|
|
474
|
+
- Hand off validated package to 02-process
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Replace `templates/.workspace-templates/workspace/02-process/CONTEXT.md` with:
|
|
478
|
+
|
|
479
|
+
```markdown
|
|
480
|
+
# 02-process CONTEXT.md
|
|
481
|
+
|
|
482
|
+
## Purpose
|
|
483
|
+
Transform validated inputs into structured working outputs.
|
|
484
|
+
|
|
485
|
+
## Inputs
|
|
486
|
+
- Validated package from 01-input
|
|
487
|
+
- Processing requirements and quality constraints
|
|
488
|
+
|
|
489
|
+
## Outputs
|
|
490
|
+
- Processed artifacts ready for final delivery
|
|
491
|
+
- Decision log for key transformations
|
|
492
|
+
|
|
493
|
+
## Dependencies
|
|
494
|
+
- 01-input
|
|
495
|
+
|
|
496
|
+
## Completion Criteria
|
|
497
|
+
- Required transformations are complete
|
|
498
|
+
- Output structure is consistent and reviewable
|
|
499
|
+
- Handoff package is ready for output stage
|
|
500
|
+
|
|
501
|
+
## Handoff
|
|
502
|
+
- Hand off processed artifacts to 03-output
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Replace `templates/.workspace-templates/workspace/03-output/CONTEXT.md` with:
|
|
506
|
+
|
|
507
|
+
```markdown
|
|
508
|
+
# 03-output CONTEXT.md
|
|
509
|
+
|
|
510
|
+
## Purpose
|
|
511
|
+
Assemble, finalize, and deliver workflow outputs.
|
|
512
|
+
|
|
513
|
+
## Inputs
|
|
514
|
+
- Processed artifacts from 02-process
|
|
515
|
+
- Delivery requirements and formatting rules
|
|
516
|
+
|
|
517
|
+
## Outputs
|
|
518
|
+
- Final deliverable package
|
|
519
|
+
- Delivery notes and validation summary
|
|
520
|
+
|
|
521
|
+
## Dependencies
|
|
522
|
+
- 02-process
|
|
523
|
+
|
|
524
|
+
## Completion Criteria
|
|
525
|
+
- Final outputs satisfy delivery requirements
|
|
526
|
+
- Validation summary is complete
|
|
527
|
+
- Artifacts are ready for handoff to user
|
|
528
|
+
|
|
529
|
+
## Handoff
|
|
530
|
+
- Final output stage: deliver package and close the workflow loop
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
- [ ] **Step 4: Run tests to verify pass**
|
|
534
|
+
|
|
535
|
+
Run:
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
npx jest tests/templates.test.ts -v
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
Expected: PASS.
|
|
542
|
+
|
|
543
|
+
- [ ] **Step 5: Commit**
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
git add tests/templates.test.ts templates/.workspace-templates/SYSTEM.md templates/.workspace-templates/CONTEXT.md templates/.workspace-templates/workspace/01-input/CONTEXT.md templates/.workspace-templates/workspace/02-process/CONTEXT.md templates/.workspace-templates/workspace/03-output/CONTEXT.md
|
|
547
|
+
git commit -m "docs(templates): align prompt templates to robust workflow contract"
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
### Task 4: Add Strict Structural Validation Tests and Implement Checks
|
|
553
|
+
|
|
554
|
+
**Files:**
|
|
555
|
+
- Modify: `tests/validate.test.ts`
|
|
556
|
+
- Modify: `src/scripts/validate.ts`
|
|
557
|
+
|
|
558
|
+
- [ ] **Step 1: Write failing tests for required root and stage sections**
|
|
559
|
+
|
|
560
|
+
In `tests/validate.test.ts`, update `createValidWorkspace()` and add tests:
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
function createValidWorkspace(): string {
|
|
564
|
+
const ws = path.join(tempDir, 'workspace');
|
|
565
|
+
fs.mkdirSync(ws, { recursive: true });
|
|
566
|
+
|
|
567
|
+
fs.writeFileSync(path.join(ws, 'SYSTEM.md'), [
|
|
568
|
+
'# Test',
|
|
569
|
+
'',
|
|
570
|
+
'## Role',
|
|
571
|
+
'Workspace role.',
|
|
572
|
+
'',
|
|
573
|
+
'## Folder Map',
|
|
574
|
+
'- 01-input/',
|
|
575
|
+
'- 02-output/',
|
|
576
|
+
'',
|
|
577
|
+
'## Workflow Rules',
|
|
578
|
+
'Follow selective loading and canonical source rules.',
|
|
579
|
+
'',
|
|
580
|
+
'## Stage Boundaries',
|
|
581
|
+
'One-way dependencies only.',
|
|
582
|
+
'',
|
|
583
|
+
'## Tooling Policy',
|
|
584
|
+
'Use tools.md for inventory.',
|
|
585
|
+
'',
|
|
586
|
+
].join('\n'));
|
|
587
|
+
|
|
588
|
+
fs.writeFileSync(path.join(ws, 'CONTEXT.md'), [
|
|
589
|
+
'# Router',
|
|
590
|
+
'',
|
|
591
|
+
'## How to Use This File',
|
|
592
|
+
'Route tasks by stage.',
|
|
593
|
+
'',
|
|
594
|
+
'## Task Routing',
|
|
595
|
+
'- 01-input/CONTEXT.md',
|
|
596
|
+
'- 02-output/CONTEXT.md',
|
|
597
|
+
'',
|
|
598
|
+
'## Loading Order',
|
|
599
|
+
'1. SYSTEM.md',
|
|
600
|
+
'2. CONTEXT.md',
|
|
601
|
+
'3. Stage CONTEXT.md',
|
|
602
|
+
'4. Task files only',
|
|
603
|
+
'',
|
|
604
|
+
'## Stage Handoff Routing',
|
|
605
|
+
'01-input -> 02-output',
|
|
606
|
+
'',
|
|
607
|
+
'## Escalation',
|
|
608
|
+
'Escalate when routing is ambiguous.',
|
|
609
|
+
'',
|
|
610
|
+
].join('\n'));
|
|
611
|
+
|
|
612
|
+
fs.mkdirSync(path.join(ws, '01-input'), { recursive: true });
|
|
613
|
+
fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), [
|
|
614
|
+
'# 01-input',
|
|
615
|
+
'',
|
|
616
|
+
'## Purpose',
|
|
617
|
+
'Input stage.',
|
|
618
|
+
'',
|
|
619
|
+
'## Inputs',
|
|
620
|
+
'Raw data.',
|
|
621
|
+
'',
|
|
622
|
+
'## Outputs',
|
|
623
|
+
'Validated data.',
|
|
624
|
+
'',
|
|
625
|
+
'## Dependencies',
|
|
626
|
+
'None.',
|
|
627
|
+
'',
|
|
628
|
+
'## Completion Criteria',
|
|
629
|
+
'Inputs validated.',
|
|
630
|
+
'',
|
|
631
|
+
'## Handoff',
|
|
632
|
+
'Hand off to 02-output.',
|
|
633
|
+
'',
|
|
634
|
+
].join('\n'));
|
|
635
|
+
|
|
636
|
+
fs.mkdirSync(path.join(ws, '02-output'), { recursive: true });
|
|
637
|
+
fs.writeFileSync(path.join(ws, '02-output', 'CONTEXT.md'), [
|
|
638
|
+
'# 02-output',
|
|
639
|
+
'',
|
|
640
|
+
'## Purpose',
|
|
641
|
+
'Output stage.',
|
|
642
|
+
'',
|
|
643
|
+
'## Inputs',
|
|
644
|
+
'Validated data.',
|
|
645
|
+
'',
|
|
646
|
+
'## Outputs',
|
|
647
|
+
'Final report.',
|
|
648
|
+
'',
|
|
649
|
+
'## Dependencies',
|
|
650
|
+
'01-input.',
|
|
651
|
+
'',
|
|
652
|
+
'## Completion Criteria',
|
|
653
|
+
'Output complete.',
|
|
654
|
+
'',
|
|
655
|
+
'## Handoff',
|
|
656
|
+
'Deliver final output.',
|
|
657
|
+
'',
|
|
658
|
+
].join('\n'));
|
|
659
|
+
|
|
660
|
+
fs.mkdirSync(path.join(ws, '00-meta'), { recursive: true });
|
|
661
|
+
fs.writeFileSync(path.join(ws, '00-meta', 'CONTEXT.md'), '# 00-meta\n\nMeta content.\n');
|
|
662
|
+
fs.writeFileSync(path.join(ws, '00-meta', 'tools.md'), '# Tools\n\n| Tool | Version |\n|------|---------|\n');
|
|
663
|
+
|
|
664
|
+
return ws;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
it('fails when SYSTEM.md misses required workflow sections', () => {
|
|
668
|
+
const ws = createValidWorkspace();
|
|
669
|
+
fs.writeFileSync(path.join(ws, 'SYSTEM.md'), '# Test\n\n## Role\nRole only\n');
|
|
670
|
+
|
|
671
|
+
const result = validateWorkspace(ws);
|
|
672
|
+
|
|
673
|
+
expect(result.passed).toBe(false);
|
|
674
|
+
expect(result.checks.some((c) => c.name.includes('SYSTEM.md contains ## Workflow Rules') && !c.passed)).toBe(true);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('fails when root CONTEXT.md misses required router sections', () => {
|
|
678
|
+
const ws = createValidWorkspace();
|
|
679
|
+
fs.writeFileSync(path.join(ws, 'CONTEXT.md'), '# Router\n\n## Task Routing\n- 01-input/CONTEXT.md\n');
|
|
680
|
+
|
|
681
|
+
const result = validateWorkspace(ws);
|
|
682
|
+
|
|
683
|
+
expect(result.passed).toBe(false);
|
|
684
|
+
expect(result.checks.some((c) => c.name.includes('CONTEXT.md contains ## Loading Order') && !c.passed)).toBe(true);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('fails when stage CONTEXT.md misses completion and handoff sections', () => {
|
|
688
|
+
const ws = createValidWorkspace();
|
|
689
|
+
fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), '# 01-input\n\n## Purpose\nInput stage\n');
|
|
690
|
+
|
|
691
|
+
const result = validateWorkspace(ws);
|
|
692
|
+
|
|
693
|
+
expect(result.passed).toBe(false);
|
|
694
|
+
expect(result.checks.some((c) => c.name.includes('01-input/CONTEXT.md contains ## Completion Criteria') && !c.passed)).toBe(true);
|
|
695
|
+
expect(result.checks.some((c) => c.name.includes('01-input/CONTEXT.md contains ## Handoff') && !c.passed)).toBe(true);
|
|
696
|
+
});
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
- [ ] **Step 2: Run tests to verify fail**
|
|
700
|
+
|
|
701
|
+
Run:
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
npx jest tests/validate.test.ts -t "required workflow sections|required router sections|completion and handoff" -v
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Expected: FAIL because validation does not check these section contracts yet.
|
|
708
|
+
|
|
709
|
+
- [ ] **Step 3: Implement structural contract checks in validate.ts**
|
|
710
|
+
|
|
711
|
+
Add constants and helper functions in `src/scripts/validate.ts`:
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
const REQUIRED_SYSTEM_HEADINGS = [
|
|
715
|
+
'## Role',
|
|
716
|
+
'## Folder Map',
|
|
717
|
+
'## Workflow Rules',
|
|
718
|
+
'## Stage Boundaries',
|
|
719
|
+
'## Tooling Policy',
|
|
720
|
+
];
|
|
721
|
+
|
|
722
|
+
const REQUIRED_ROOT_CONTEXT_HEADINGS = [
|
|
723
|
+
'## How to Use This File',
|
|
724
|
+
'## Task Routing',
|
|
725
|
+
'## Loading Order',
|
|
726
|
+
'## Stage Handoff Routing',
|
|
727
|
+
'## Escalation',
|
|
728
|
+
];
|
|
729
|
+
|
|
730
|
+
const REQUIRED_STAGE_CONTEXT_HEADINGS = [
|
|
731
|
+
'## Purpose',
|
|
732
|
+
'## Inputs',
|
|
733
|
+
'## Outputs',
|
|
734
|
+
'## Dependencies',
|
|
735
|
+
'## Completion Criteria',
|
|
736
|
+
'## Handoff',
|
|
737
|
+
];
|
|
738
|
+
|
|
739
|
+
function escapeRegExp(value: string): string {
|
|
740
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
function hasHeading(content: string, heading: string): boolean {
|
|
744
|
+
return new RegExp(`^${escapeRegExp(heading)}\\s*$`, 'im').test(content);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function addRequiredHeadingChecks(
|
|
748
|
+
fileLabel: string,
|
|
749
|
+
content: string,
|
|
750
|
+
headings: string[],
|
|
751
|
+
checks: CheckResult[],
|
|
752
|
+
): void {
|
|
753
|
+
for (const heading of headings) {
|
|
754
|
+
const found = hasHeading(content, heading);
|
|
755
|
+
checks.push({
|
|
756
|
+
name: `${fileLabel} contains ${heading}`,
|
|
757
|
+
passed: found,
|
|
758
|
+
message: found ? 'Found' : `Missing ${heading}`,
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Integrate into `validateWorkspace()` after reading files:
|
|
765
|
+
|
|
766
|
+
```typescript
|
|
767
|
+
if (systemExists) {
|
|
768
|
+
const systemContent = fs.readFileSync(systemMdPath, 'utf-8');
|
|
769
|
+
addRequiredHeadingChecks('SYSTEM.md', systemContent, REQUIRED_SYSTEM_HEADINGS, checks);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (contextExists) {
|
|
773
|
+
const contextContent = fs.readFileSync(contextMdPath, 'utf-8');
|
|
774
|
+
addRequiredHeadingChecks('CONTEXT.md', contextContent, REQUIRED_ROOT_CONTEXT_HEADINGS, checks);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
for (const folder of numberedFolders) {
|
|
778
|
+
const contextPath = path.join(ws, folder, 'CONTEXT.md');
|
|
779
|
+
const exists = fs.existsSync(contextPath);
|
|
780
|
+
// existing exists/non-empty checks
|
|
781
|
+
|
|
782
|
+
if (exists) {
|
|
783
|
+
const content = fs.readFileSync(contextPath, 'utf-8');
|
|
784
|
+
addRequiredHeadingChecks(`${folder}/CONTEXT.md`, content, REQUIRED_STAGE_CONTEXT_HEADINGS, checks);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
- [ ] **Step 4: Run tests to verify pass**
|
|
790
|
+
|
|
791
|
+
Run:
|
|
792
|
+
|
|
793
|
+
```bash
|
|
794
|
+
npx jest tests/validate.test.ts -t "required workflow sections|required router sections|completion and handoff" -v
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
Expected: PASS.
|
|
798
|
+
|
|
799
|
+
- [ ] **Step 5: Commit**
|
|
800
|
+
|
|
801
|
+
```bash
|
|
802
|
+
git add tests/validate.test.ts src/scripts/validate.ts
|
|
803
|
+
git commit -m "feat(validate): enforce required prompt section contracts"
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
---
|
|
807
|
+
|
|
808
|
+
### Task 5: Add Workflow-Semantic Validation (Routing Coverage + Dependency Direction)
|
|
809
|
+
|
|
810
|
+
**Files:**
|
|
811
|
+
- Modify: `tests/validate.test.ts`
|
|
812
|
+
- Modify: `src/scripts/validate.ts`
|
|
813
|
+
|
|
814
|
+
- [ ] **Step 1: Write failing tests for routing coverage and dependency direction**
|
|
815
|
+
|
|
816
|
+
Add tests to `tests/validate.test.ts`:
|
|
817
|
+
|
|
818
|
+
```typescript
|
|
819
|
+
it('fails when root routing misses a numbered stage folder', () => {
|
|
820
|
+
const ws = createValidWorkspace();
|
|
821
|
+
fs.writeFileSync(path.join(ws, 'CONTEXT.md'), [
|
|
822
|
+
'# Router',
|
|
823
|
+
'',
|
|
824
|
+
'## How to Use This File',
|
|
825
|
+
'Route tasks by stage.',
|
|
826
|
+
'',
|
|
827
|
+
'## Task Routing',
|
|
828
|
+
'- 01-input/CONTEXT.md',
|
|
829
|
+
'',
|
|
830
|
+
'## Loading Order',
|
|
831
|
+
'1. SYSTEM.md',
|
|
832
|
+
'2. CONTEXT.md',
|
|
833
|
+
'3. Stage CONTEXT.md',
|
|
834
|
+
'4. Task files only',
|
|
835
|
+
'',
|
|
836
|
+
'## Stage Handoff Routing',
|
|
837
|
+
'01-input -> 02-output',
|
|
838
|
+
'',
|
|
839
|
+
'## Escalation',
|
|
840
|
+
'Escalate when routing is ambiguous.',
|
|
841
|
+
'',
|
|
842
|
+
].join('\n'));
|
|
843
|
+
|
|
844
|
+
const result = validateWorkspace(ws);
|
|
845
|
+
|
|
846
|
+
expect(result.passed).toBe(false);
|
|
847
|
+
expect(result.checks.some((c) => c.name.includes('Root routing references all numbered stages') && !c.passed)).toBe(true);
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
it('fails when stage dependencies point to a later stage number', () => {
|
|
851
|
+
const ws = createValidWorkspace();
|
|
852
|
+
fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), [
|
|
853
|
+
'# 01-input',
|
|
854
|
+
'',
|
|
855
|
+
'## Purpose',
|
|
856
|
+
'Input stage.',
|
|
857
|
+
'',
|
|
858
|
+
'## Inputs',
|
|
859
|
+
'Raw data.',
|
|
860
|
+
'',
|
|
861
|
+
'## Outputs',
|
|
862
|
+
'Validated data.',
|
|
863
|
+
'',
|
|
864
|
+
'## Dependencies',
|
|
865
|
+
'02-output',
|
|
866
|
+
'',
|
|
867
|
+
'## Completion Criteria',
|
|
868
|
+
'Inputs validated.',
|
|
869
|
+
'',
|
|
870
|
+
'## Handoff',
|
|
871
|
+
'Hand off to 02-output.',
|
|
872
|
+
'',
|
|
873
|
+
].join('\n'));
|
|
874
|
+
|
|
875
|
+
const result = validateWorkspace(ws);
|
|
876
|
+
|
|
877
|
+
expect(result.passed).toBe(false);
|
|
878
|
+
expect(result.checks.some((c) => c.name.includes('01-input dependencies do not point to later stages') && !c.passed)).toBe(true);
|
|
879
|
+
});
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
- [ ] **Step 2: Run tests to verify fail**
|
|
883
|
+
|
|
884
|
+
Run:
|
|
885
|
+
|
|
886
|
+
```bash
|
|
887
|
+
npx jest tests/validate.test.ts -t "routing misses|later stage number" -v
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
Expected: FAIL because routing coverage and dependency direction checks do not exist yet.
|
|
891
|
+
|
|
892
|
+
- [ ] **Step 3: Implement routing and dependency semantic checks**
|
|
893
|
+
|
|
894
|
+
In `src/scripts/validate.ts`, add helpers:
|
|
895
|
+
|
|
896
|
+
```typescript
|
|
897
|
+
function getNumberedStageFolders(workspacePath: string): string[] {
|
|
898
|
+
const entries = fs.readdirSync(workspacePath, { withFileTypes: true });
|
|
899
|
+
return entries
|
|
900
|
+
.filter((entry) => entry.isDirectory() && /^\d{2}-/.test(entry.name) && entry.name !== '00-meta')
|
|
901
|
+
.map((entry) => entry.name);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
function extractDependenciesSection(content: string): string {
|
|
905
|
+
const match = content.match(/## Dependencies\s*([\s\S]*?)(?=\n##\s|$)/i);
|
|
906
|
+
return match ? match[1] : '';
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
function extractStageRefs(content: string): string[] {
|
|
910
|
+
const refs = new Set<string>();
|
|
911
|
+
const regex = /(\d{2}-[A-Za-z0-9-_]+)/g;
|
|
912
|
+
let match: RegExpExecArray | null;
|
|
913
|
+
while ((match = regex.exec(content)) !== null) {
|
|
914
|
+
refs.add(match[1]);
|
|
915
|
+
}
|
|
916
|
+
return Array.from(refs);
|
|
917
|
+
}
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
Then in `validateWorkspace()`:
|
|
921
|
+
|
|
922
|
+
```typescript
|
|
923
|
+
const numberedFolders = getNumberedStageFolders(ws);
|
|
924
|
+
|
|
925
|
+
if (contextExists) {
|
|
926
|
+
const rootContext = fs.readFileSync(contextMdPath, 'utf-8');
|
|
927
|
+
const allReferenced = numberedFolders.every((folder) => rootContext.includes(`${folder}/CONTEXT.md`));
|
|
928
|
+
checks.push({
|
|
929
|
+
name: 'Root routing references all numbered stages',
|
|
930
|
+
passed: allReferenced,
|
|
931
|
+
message: allReferenced ? 'All numbered stages are routed' : 'Missing one or more numbered stage routes',
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
const enforcesSelectiveLoading =
|
|
935
|
+
/## Loading Order/i.test(rootContext) &&
|
|
936
|
+
/SYSTEM\.md/i.test(rootContext) &&
|
|
937
|
+
/Only the task files needed/i.test(rootContext);
|
|
938
|
+
|
|
939
|
+
checks.push({
|
|
940
|
+
name: 'Root loading order enforces selective loading',
|
|
941
|
+
passed: enforcesSelectiveLoading,
|
|
942
|
+
message: enforcesSelectiveLoading ? 'Selective loading guidance found' : 'Loading order lacks selective-loading guidance',
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
for (const folder of numberedFolders) {
|
|
947
|
+
const stagePath = path.join(ws, folder, 'CONTEXT.md');
|
|
948
|
+
if (!fs.existsSync(stagePath)) {
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const stageContent = fs.readFileSync(stagePath, 'utf-8');
|
|
953
|
+
const deps = extractStageRefs(extractDependenciesSection(stageContent));
|
|
954
|
+
const currentNum = parseInt(folder.slice(0, 2), 10);
|
|
955
|
+
const pointsToLaterStage = deps.some((dep) => parseInt(dep.slice(0, 2), 10) > currentNum);
|
|
956
|
+
|
|
957
|
+
checks.push({
|
|
958
|
+
name: `${folder} dependencies do not point to later stages`,
|
|
959
|
+
passed: !pointsToLaterStage,
|
|
960
|
+
message: !pointsToLaterStage ? 'Dependency direction valid' : 'Found dependency on later-numbered stage',
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
- [ ] **Step 4: Run tests to verify pass**
|
|
966
|
+
|
|
967
|
+
Run:
|
|
968
|
+
|
|
969
|
+
```bash
|
|
970
|
+
npx jest tests/validate.test.ts -t "routing misses|later stage number" -v
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
Expected: PASS.
|
|
974
|
+
|
|
975
|
+
- [ ] **Step 5: Commit**
|
|
976
|
+
|
|
977
|
+
```bash
|
|
978
|
+
git add tests/validate.test.ts src/scripts/validate.ts
|
|
979
|
+
git commit -m "feat(validate): enforce routing coverage and dependency direction"
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
---
|
|
983
|
+
|
|
984
|
+
### Task 6: Full Regression Verification
|
|
985
|
+
|
|
986
|
+
**Files:**
|
|
987
|
+
- Verify-only: no planned file edits
|
|
988
|
+
|
|
989
|
+
- [ ] **Step 1: Run focused prompt-hardening suites**
|
|
990
|
+
|
|
991
|
+
Run:
|
|
992
|
+
|
|
993
|
+
```bash
|
|
994
|
+
npx jest tests/scaffold.test.ts tests/validate.test.ts tests/templates.test.ts -v
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
Expected: PASS for all targeted suites.
|
|
998
|
+
|
|
999
|
+
- [ ] **Step 2: Run full test suite**
|
|
1000
|
+
|
|
1001
|
+
Run:
|
|
1002
|
+
|
|
1003
|
+
```bash
|
|
1004
|
+
npm test
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
Expected: PASS with 0 failing suites.
|
|
1008
|
+
|
|
1009
|
+
- [ ] **Step 3: Run TypeScript build**
|
|
1010
|
+
|
|
1011
|
+
Run:
|
|
1012
|
+
|
|
1013
|
+
```bash
|
|
1014
|
+
npm run build
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
Expected: `tsc` completes with no errors.
|
|
1018
|
+
|
|
1019
|
+
- [ ] **Step 4: Final verification commit (only if additional fixes were needed during regression)**
|
|
1020
|
+
|
|
1021
|
+
```bash
|
|
1022
|
+
git status
|
|
1023
|
+
git add -A
|
|
1024
|
+
git commit -m "chore: finalize workflow prompt hardening verification"
|
|
1025
|
+
```
|