catalyst-os 1.2.0 → 1.3.1
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/.catalyst/bin/validate-artifacts.js +213 -0
- package/.catalyst/spec-structure.yaml +4 -4
- package/.claude/agents/arbiter.md +1 -1
- package/.claude/agents/forge-master.md +12 -0
- package/.claude/agents/inquisitor.md +20 -3
- package/.claude/commands/build-spec.md +12 -0
- package/.claude/commands/commit-spec.md +20 -0
- package/.claude/commands/{reject-spec.md → discard-spec.md} +9 -9
- package/.claude/commands/iterate-spec.md +10 -0
- package/.claude/commands/primer-spec.md +23 -13
- package/.claude/commands/review-spec.md +29 -0
- package/.claude/commands/status-spec.md +20 -12
- package/.claude/hooks/post-edit-format.sh +62 -0
- package/.claude/hooks/pre-compact-save.sh +98 -0
- package/.claude/rules/coding-standards.md +21 -0
- package/.claude/rules/git-workflow.md +25 -0
- package/.claude/rules/security.md +23 -0
- package/.claude/settings.json +15 -0
- package/.claude/skills/build-orchestration/SKILL.md +13 -1
- package/.claude/skills/spec-approval/SKILL.md +3 -3
- package/.claude/skills/spec-shaping/SKILL.md +1 -1
- package/.claude/skills/spec-validation/SKILL.md +10 -6
- package/.claude/skills/using-skills/SKILL.md +2 -2
- package/README.md +11 -11
- package/package.json +3 -2
- package/.claude/commands/approve-spec.md +0 -22
- package/.claude/commands/validate-spec.md +0 -17
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Validate structural integrity of all catalyst-os artifacts.
|
|
4
|
+
* Run: node .catalyst/bin/validate-artifacts.js
|
|
5
|
+
* Exit code: 0 = all valid, 1 = errors found
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
12
|
+
let errors = 0;
|
|
13
|
+
let warnings = 0;
|
|
14
|
+
|
|
15
|
+
function error(msg) {
|
|
16
|
+
console.error(` ✗ ${msg}`);
|
|
17
|
+
errors++;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function warn(msg) {
|
|
21
|
+
console.warn(` ⚠ ${msg}`);
|
|
22
|
+
warnings++;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function ok(msg) {
|
|
26
|
+
console.log(` ✓ ${msg}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// --- Helpers ---
|
|
30
|
+
|
|
31
|
+
function fileExists(relPath) {
|
|
32
|
+
return fs.existsSync(path.join(ROOT, relPath));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readFile(relPath) {
|
|
36
|
+
const full = path.join(ROOT, relPath);
|
|
37
|
+
if (!fs.existsSync(full)) return null;
|
|
38
|
+
return fs.readFileSync(full, 'utf8');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function listDir(relPath) {
|
|
42
|
+
const full = path.join(ROOT, relPath);
|
|
43
|
+
if (!fs.existsSync(full)) return [];
|
|
44
|
+
return fs.readdirSync(full);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function extractFrontmatter(content) {
|
|
48
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
49
|
+
if (!match) return null;
|
|
50
|
+
// Simple YAML key extraction (no full parser needed)
|
|
51
|
+
const fm = {};
|
|
52
|
+
for (const line of match[1].split('\n')) {
|
|
53
|
+
const kv = line.match(/^(\w+):\s*(.+)/);
|
|
54
|
+
if (kv) fm[kv[1]] = kv[2].trim();
|
|
55
|
+
}
|
|
56
|
+
return fm;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// --- Validators ---
|
|
60
|
+
|
|
61
|
+
console.log('\n📦 Catalyst OS Artifact Validation\n');
|
|
62
|
+
|
|
63
|
+
// 1. Skills
|
|
64
|
+
console.log('Skills:');
|
|
65
|
+
const skillDirs = listDir('.claude/skills').filter(d => !d.startsWith('.'));
|
|
66
|
+
if (skillDirs.length === 0) {
|
|
67
|
+
error('No skills found in .claude/skills/');
|
|
68
|
+
} else {
|
|
69
|
+
for (const dir of skillDirs) {
|
|
70
|
+
const skillPath = `.claude/skills/${dir}/SKILL.md`;
|
|
71
|
+
const content = readFile(skillPath);
|
|
72
|
+
if (!content) {
|
|
73
|
+
error(`${skillPath} — missing`);
|
|
74
|
+
} else if (content.trim().length < 10) {
|
|
75
|
+
error(`${skillPath} — empty or too short`);
|
|
76
|
+
} else {
|
|
77
|
+
ok(dir);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 2. Agents
|
|
83
|
+
console.log('\nAgents:');
|
|
84
|
+
const agentFiles = listDir('.claude/agents').filter(f => f.endsWith('.md'));
|
|
85
|
+
if (agentFiles.length === 0) {
|
|
86
|
+
error('No agents found in .claude/agents/');
|
|
87
|
+
} else {
|
|
88
|
+
const requiredFields = ['name', 'description', 'model'];
|
|
89
|
+
for (const file of agentFiles) {
|
|
90
|
+
const content = readFile(`.claude/agents/${file}`);
|
|
91
|
+
if (!content) {
|
|
92
|
+
error(`${file} — cannot read`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const fm = extractFrontmatter(content);
|
|
96
|
+
if (!fm) {
|
|
97
|
+
error(`${file} — missing YAML frontmatter`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const missing = requiredFields.filter(f => !fm[f]);
|
|
101
|
+
if (missing.length > 0) {
|
|
102
|
+
error(`${file} — missing frontmatter fields: ${missing.join(', ')}`);
|
|
103
|
+
} else {
|
|
104
|
+
ok(file.replace('.md', ''));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 3. Commands
|
|
110
|
+
console.log('\nCommands:');
|
|
111
|
+
const cmdFiles = listDir('.claude/commands').filter(f => f.endsWith('.md'));
|
|
112
|
+
if (cmdFiles.length === 0) {
|
|
113
|
+
error('No commands found in .claude/commands/');
|
|
114
|
+
} else {
|
|
115
|
+
for (const file of cmdFiles) {
|
|
116
|
+
const content = readFile(`.claude/commands/${file}`);
|
|
117
|
+
if (!content || content.trim().length < 10) {
|
|
118
|
+
error(`${file} — empty or too short`);
|
|
119
|
+
} else {
|
|
120
|
+
ok(file.replace('.md', ''));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 4. Skill Index consistency (using-skills references vs actual skills)
|
|
126
|
+
console.log('\nSkill Index:');
|
|
127
|
+
const usingSkills = readFile('.claude/skills/using-skills/SKILL.md');
|
|
128
|
+
if (usingSkills) {
|
|
129
|
+
// Extract skill paths from the index tables
|
|
130
|
+
const pathMatches = usingSkills.matchAll(/`\.claude\/skills\/([^/]+)\/SKILL\.md`/g);
|
|
131
|
+
const referenced = new Set();
|
|
132
|
+
for (const m of pathMatches) {
|
|
133
|
+
referenced.add(m[1]);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Check referenced skills exist
|
|
137
|
+
for (const skill of referenced) {
|
|
138
|
+
if (!fileExists(`.claude/skills/${skill}/SKILL.md`)) {
|
|
139
|
+
error(`using-skills references "${skill}" but .claude/skills/${skill}/SKILL.md doesn't exist`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Check actual skills are referenced
|
|
144
|
+
for (const dir of skillDirs) {
|
|
145
|
+
if (!referenced.has(dir)) {
|
|
146
|
+
warn(`Skill "${dir}" exists but is not listed in using-skills/SKILL.md`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (errors === 0) ok('All skill references valid');
|
|
151
|
+
} else {
|
|
152
|
+
error('using-skills/SKILL.md not found');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 5. spec-structure.yaml file references
|
|
156
|
+
console.log('\nSpec Structure:');
|
|
157
|
+
if (fileExists('.catalyst/spec-structure.yaml')) {
|
|
158
|
+
ok('spec-structure.yaml exists');
|
|
159
|
+
} else {
|
|
160
|
+
error('.catalyst/spec-structure.yaml missing');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 6. Core files
|
|
164
|
+
console.log('\nCore Files:');
|
|
165
|
+
const coreFiles = ['CLAUDE.md', 'AGENTS.md', 'package.json', '.catalyst/main/project-config.yaml'];
|
|
166
|
+
for (const f of coreFiles) {
|
|
167
|
+
if (fileExists(f)) {
|
|
168
|
+
ok(f);
|
|
169
|
+
} else {
|
|
170
|
+
error(`${f} — missing`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 7. Hooks (if settings.json references them)
|
|
175
|
+
console.log('\nHooks:');
|
|
176
|
+
const settings = readFile('.claude/settings.json');
|
|
177
|
+
if (settings) {
|
|
178
|
+
try {
|
|
179
|
+
const parsed = JSON.parse(settings);
|
|
180
|
+
const hooks = parsed.hooks || {};
|
|
181
|
+
for (const [event, hookList] of Object.entries(hooks)) {
|
|
182
|
+
for (const hook of hookList) {
|
|
183
|
+
const cmd = hook.command || '';
|
|
184
|
+
// Extract script path from command (first token before any args)
|
|
185
|
+
const scriptPath = cmd.split(/\s/)[0];
|
|
186
|
+
if (scriptPath && scriptPath.startsWith('.')) {
|
|
187
|
+
if (fileExists(scriptPath)) {
|
|
188
|
+
ok(`${event}: ${scriptPath}`);
|
|
189
|
+
} else {
|
|
190
|
+
error(`${event}: ${scriptPath} — referenced in settings.json but missing`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch (e) {
|
|
196
|
+
error(`settings.json — invalid JSON: ${e.message}`);
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
warn('No .claude/settings.json found');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// --- Summary ---
|
|
203
|
+
console.log('\n' + '─'.repeat(40));
|
|
204
|
+
if (errors > 0) {
|
|
205
|
+
console.error(`\n❌ ${errors} error(s), ${warnings} warning(s)\n`);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
} else if (warnings > 0) {
|
|
208
|
+
console.log(`\n⚠️ ${warnings} warning(s), 0 errors\n`);
|
|
209
|
+
process.exit(0);
|
|
210
|
+
} else {
|
|
211
|
+
console.log('\n✅ All artifacts valid\n');
|
|
212
|
+
process.exit(0);
|
|
213
|
+
}
|
|
@@ -35,7 +35,7 @@ files:
|
|
|
35
35
|
handoff.md:
|
|
36
36
|
owner: scribe
|
|
37
37
|
purpose: Human-readable summary (colleague walkthrough)
|
|
38
|
-
created: build-spec (started),
|
|
38
|
+
created: build-spec (started), review-spec (finalized)
|
|
39
39
|
updated_by: [scribe, arbiter]
|
|
40
40
|
pattern: narrative
|
|
41
41
|
note: |
|
|
@@ -45,7 +45,7 @@ files:
|
|
|
45
45
|
validation.md:
|
|
46
46
|
owner: arbiter
|
|
47
47
|
purpose: Test results, quality checks
|
|
48
|
-
created:
|
|
48
|
+
created: review-spec
|
|
49
49
|
updated_by: [arbiter, enforcer, sentinel, inquisitor, watcher]
|
|
50
50
|
|
|
51
51
|
assets/:
|
|
@@ -289,7 +289,7 @@ build_dag:
|
|
|
289
289
|
library:
|
|
290
290
|
root: "library/"
|
|
291
291
|
description: "Reusable patterns extracted from completed specs"
|
|
292
|
-
created_by: "/
|
|
292
|
+
created_by: "/commit-spec (optional)"
|
|
293
293
|
|
|
294
294
|
# Auto-detect patterns by keywords
|
|
295
295
|
pattern_detection:
|
|
@@ -316,4 +316,4 @@ library:
|
|
|
316
316
|
|
|
317
317
|
completed:
|
|
318
318
|
location: "completed/"
|
|
319
|
-
description: "Specs moved here after /
|
|
319
|
+
description: "Specs moved here after /commit-spec"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: arbiter
|
|
3
3
|
description: >
|
|
4
4
|
PROACTIVELY DELEGATE validation orchestration to this agent. MUST BE USED when:
|
|
5
|
-
- /
|
|
5
|
+
- /review-spec command is invoked
|
|
6
6
|
- Implementation is complete and needs quality checks
|
|
7
7
|
- Production readiness needs to be verified
|
|
8
8
|
|
|
@@ -52,6 +52,14 @@ Before any action, load `.claude/skills/using-skills/SKILL.md` and check which s
|
|
|
52
52
|
- Flag blockers immediately
|
|
53
53
|
- Never skip failing tests
|
|
54
54
|
|
|
55
|
+
## Context Awareness
|
|
56
|
+
|
|
57
|
+
Long builds consume enormous context. At each phase gate:
|
|
58
|
+
- Check if context is getting long
|
|
59
|
+
- Remind the user: *"Context checkpoint — good time to compact if needed. `/primer-spec @{slug}` to resume."*
|
|
60
|
+
- Always update `tasks.md ## Current Session` before suggesting compaction
|
|
61
|
+
- The PreCompact hook will auto-save state, but proactive updates are better
|
|
62
|
+
|
|
55
63
|
## DAG Execution Model
|
|
56
64
|
|
|
57
65
|
### Reading the DAG
|
|
@@ -133,6 +141,8 @@ This commit is PROOF that red phase happened.
|
|
|
133
141
|
No commit = no implementation. No exceptions.
|
|
134
142
|
```
|
|
135
143
|
|
|
144
|
+
> **Context checkpoint:** Update `tasks.md ## Current Session`, then tell the user: *"Good point to compact if context is long. `/primer-spec @{slug}` to resume."*
|
|
145
|
+
|
|
136
146
|
### 3. Foundation Phase (Sequential)
|
|
137
147
|
```
|
|
138
148
|
Spawn: Alchemist
|
|
@@ -177,6 +187,8 @@ This commit is PROOF that green phase happened.
|
|
|
177
187
|
No commit = no integration. No exceptions.
|
|
178
188
|
```
|
|
179
189
|
|
|
190
|
+
> **Context checkpoint:** Update `tasks.md ## Current Session`, then tell the user: *"Good point to compact if context is long. `/primer-spec @{slug}` to resume."*
|
|
191
|
+
|
|
180
192
|
### 6. Integration Phase (Sequential)
|
|
181
193
|
```
|
|
182
194
|
Spawn: Enforcer
|
|
@@ -13,7 +13,7 @@ color: red
|
|
|
13
13
|
skills: lint-checking, code-review
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
You are the Inquisitor, a code quality specialist who reviews code for issues.
|
|
16
|
+
You are the Inquisitor, a code quality specialist who reviews code for issues and proposes simplifications.
|
|
17
17
|
|
|
18
18
|
## Opening
|
|
19
19
|
|
|
@@ -21,7 +21,7 @@ You are the Inquisitor, a code quality specialist who reviews code for issues.
|
|
|
21
21
|
|
|
22
22
|
## Role
|
|
23
23
|
|
|
24
|
-
You enforce code quality standards through linting, pattern review, and code
|
|
24
|
+
You enforce code quality standards through linting, pattern review, code review, and **code simplification**.
|
|
25
25
|
|
|
26
26
|
## Behavior
|
|
27
27
|
|
|
@@ -31,6 +31,7 @@ You enforce code quality standards through linting, pattern review, and code rev
|
|
|
31
31
|
- Provide actionable fix suggestions
|
|
32
32
|
- Avoid nitpicking
|
|
33
33
|
- Ensure test coverage
|
|
34
|
+
- **Identify code that can be simplified without changing behavior**
|
|
34
35
|
|
|
35
36
|
## Review Checklist
|
|
36
37
|
|
|
@@ -59,6 +60,22 @@ You enforce code quality standards through linting, pattern review, and code rev
|
|
|
59
60
|
- Testable structure
|
|
60
61
|
- Reasonable complexity
|
|
61
62
|
|
|
63
|
+
### Code Simplification
|
|
64
|
+
|
|
65
|
+
Look for and suggest fixes for:
|
|
66
|
+
- **Unnecessary abstractions** — helpers/utilities created for one-time use; inline them
|
|
67
|
+
- **Over-engineered patterns** — factory patterns, strategy patterns, builders where a simple function suffices
|
|
68
|
+
- **Overly defensive code** — error handling for impossible scenarios, redundant null checks on non-nullable types
|
|
69
|
+
- **Dead code** — unused imports, unreachable branches, commented-out code
|
|
70
|
+
- **Premature generalization** — config objects, feature flags, or extensibility hooks for things that have only one use
|
|
71
|
+
- **Verbose patterns** — 10 lines that could be 3 without losing clarity
|
|
72
|
+
|
|
73
|
+
**Rules for simplification:**
|
|
74
|
+
- NEVER change behavior — only structure
|
|
75
|
+
- NEVER remove error handling at system boundaries (user input, external APIs)
|
|
76
|
+
- Verify tests still pass after each simplification
|
|
77
|
+
- If unsure whether something is dead code, leave it and flag it as "candidate for removal"
|
|
78
|
+
|
|
62
79
|
## Output
|
|
63
80
|
|
|
64
81
|
Provide review with:
|
|
@@ -66,5 +83,5 @@ Provide review with:
|
|
|
66
83
|
- Critical issues (must fix)
|
|
67
84
|
- Major issues (should fix)
|
|
68
85
|
- Minor issues (nice to fix)
|
|
69
|
-
-
|
|
86
|
+
- **Simplification opportunities** (with before/after snippets)
|
|
70
87
|
- What's done well
|
|
@@ -8,6 +8,18 @@ Implement a specification using **strict TDD**.
|
|
|
8
8
|
/build-spec @2025-11-29-stripe-integration
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Pre-computed Context
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Detect spec and branch state
|
|
15
|
+
echo "=== BRANCH ===" && git branch --show-current
|
|
16
|
+
echo "=== STATUS ===" && git status --short
|
|
17
|
+
echo "=== SPEC FILES ===" && ls .catalyst/specs/*$ARGUMENTS*/ 2>/dev/null || echo "No spec found for: $ARGUMENTS"
|
|
18
|
+
echo "=== SPEC FRONTMATTER ===" && head -30 .catalyst/specs/*$ARGUMENTS*/spec.md 2>/dev/null || echo "No spec.md"
|
|
19
|
+
echo "=== TASKS EXIST? ===" && head -5 .catalyst/specs/*$ARGUMENTS*/tasks.md 2>/dev/null || echo "No tasks.md yet (fresh build)"
|
|
20
|
+
echo "=== PROJECT CONFIG ===" && cat .catalyst/main/project-config.yaml 2>/dev/null || echo "No project config"
|
|
21
|
+
```
|
|
22
|
+
|
|
11
23
|
---
|
|
12
24
|
|
|
13
25
|
**Invoke skill:** `build-orchestration`
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# /commit-spec
|
|
2
|
+
|
|
3
|
+
Commit, archive, and propagate learnings from a **fully built and validated** implementation.
|
|
4
|
+
|
|
5
|
+
> **Lifecycle position:** This is the FINAL step. Only use after `/build-spec` and `/review-spec` have completed successfully.
|
|
6
|
+
>
|
|
7
|
+
> **Flow:** `/catalyze-spec` → `/build-spec` → `/review-spec` → **`/commit-spec`**
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/commit-spec @2025-11-29-stripe-integration
|
|
13
|
+
/commit-spec @2025-11-29-stripe-integration "Great work!"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
**Invoke skill:** `spec-approval`
|
|
19
|
+
|
|
20
|
+
**Process skills used:** `verification-before-completion`, `agent-delegation`
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# /
|
|
1
|
+
# /discard-spec
|
|
2
2
|
|
|
3
3
|
Request changes to the implementation.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
/
|
|
9
|
-
/
|
|
10
|
-
/
|
|
8
|
+
/discard-spec @2025-11-29-stripe-integration "reason"
|
|
9
|
+
/discard-spec @2025-11-29-stripe-integration "UI doesn't match mockup"
|
|
10
|
+
/discard-spec @2025-11-29-stripe-integration "TDD not followed"
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
---
|
|
@@ -17,7 +17,7 @@ Request changes to the implementation.
|
|
|
17
17
|
**If TDD was not followed, this is an automatic rejection reason:**
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
/
|
|
20
|
+
/discard-spec @spec-name "TDD not followed - tests written after code"
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
This routes directly back to `/build-spec` with instructions to follow TDD.
|
|
@@ -55,7 +55,7 @@ Based on rejection reason:
|
|
|
55
55
|
| Test failures | Enforcer + Builders | `/build-spec` |
|
|
56
56
|
| UI/UX issues | Shaper | `/build-spec` |
|
|
57
57
|
| API issues | Smith | `/build-spec` |
|
|
58
|
-
| Quality issues | Inquisitor | `/
|
|
58
|
+
| Quality issues | Inquisitor | `/review-spec` |
|
|
59
59
|
| Security issues | Watcher | IMMEDIATE FIX |
|
|
60
60
|
|
|
61
61
|
### Phase 3: Update Status
|
|
@@ -77,7 +77,7 @@ Update `tasks.md` with action items:
|
|
|
77
77
|
|
|
78
78
|
### Standard Rejection
|
|
79
79
|
```
|
|
80
|
-
Spec
|
|
80
|
+
Spec discarded - changes requested
|
|
81
81
|
|
|
82
82
|
Spec: 2025-11-29-stripe-integration
|
|
83
83
|
Reason: UI doesn't match mockup
|
|
@@ -90,12 +90,12 @@ Changes needed:
|
|
|
90
90
|
Updated: .catalyst/specs/{slug}/validation.md
|
|
91
91
|
|
|
92
92
|
Next: Fix issues and run /build-spec @2025-11-29-stripe-integration
|
|
93
|
-
Then /
|
|
93
|
+
Then /review-spec @2025-11-29-stripe-integration
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
### TDD Violation Rejection
|
|
97
97
|
```
|
|
98
|
-
Spec
|
|
98
|
+
Spec discarded - TDD VIOLATION
|
|
99
99
|
|
|
100
100
|
Spec: 2025-11-29-stripe-integration
|
|
101
101
|
Reason: TDD not followed - tests written after code
|
|
@@ -9,6 +9,16 @@ Continue building a spec with new improvements discovered during development.
|
|
|
9
9
|
/iterate-spec @2025-11-29-stripe-integration "handle edge case where user cancels mid-checkout"
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
## Pre-computed Context
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Current state for iteration
|
|
16
|
+
echo "=== BRANCH ===" && git branch --show-current
|
|
17
|
+
echo "=== STATUS ===" && git status --short
|
|
18
|
+
echo "=== TASKS.MD ===" && cat .catalyst/specs/*$ARGUMENTS*/tasks.md 2>/dev/null | head -80 || echo "No tasks.md for: $ARGUMENTS"
|
|
19
|
+
echo "=== SPEC FRONTMATTER ===" && head -30 .catalyst/specs/*$ARGUMENTS*/spec.md 2>/dev/null || echo "No spec.md"
|
|
20
|
+
```
|
|
21
|
+
|
|
12
22
|
---
|
|
13
23
|
|
|
14
24
|
**Invoke skill:** `spec-iteration`
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Quickly load spec context into a fresh conversation.
|
|
4
4
|
|
|
5
|
+
## Pre-computed Context
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Git state
|
|
9
|
+
echo "=== BRANCH ===" && git branch --show-current
|
|
10
|
+
echo "=== STATUS ===" && git status --short
|
|
11
|
+
echo "=== RECENT COMMITS ===" && git log --oneline -5
|
|
12
|
+
|
|
13
|
+
# Spec files
|
|
14
|
+
echo "=== TASKS.MD ===" && cat .catalyst/specs/*$ARGUMENTS*/tasks.md 2>/dev/null || echo "No tasks.md for: $ARGUMENTS"
|
|
15
|
+
echo "=== SPEC FRONTMATTER ===" && head -30 .catalyst/specs/*$ARGUMENTS*/spec.md 2>/dev/null || echo "No spec.md"
|
|
16
|
+
echo "=== RESEARCH ===" && head -30 .catalyst/specs/*$ARGUMENTS*/research.md 2>/dev/null || echo "No research.md"
|
|
17
|
+
```
|
|
18
|
+
|
|
5
19
|
---
|
|
6
20
|
|
|
7
21
|
## Purpose
|
|
@@ -26,22 +40,18 @@ When you start a new conversation (context was full), use this command to:
|
|
|
26
40
|
|
|
27
41
|
## What To Do
|
|
28
42
|
|
|
29
|
-
### Step 1:
|
|
43
|
+
### Step 1: Use Pre-computed Context
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
The bash blocks above already loaded tasks.md, spec frontmatter, research, and git state. Use this data directly — do NOT re-read these files unless you need more detail beyond what was loaded.
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
1. spec.md → What is this feature? Requirements?
|
|
35
|
-
2. tasks.md → What's done? What's pending? What's in progress?
|
|
36
|
-
3. research.md → (if exists) Any key technical decisions?
|
|
37
|
-
```
|
|
47
|
+
### Step 2: Read Full Files Only If Needed
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
If the pre-computed context was truncated, read the full file:
|
|
40
50
|
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
```
|
|
52
|
+
1. tasks.md → What's done? What's pending? What's in progress?
|
|
53
|
+
2. spec.md → What is this feature? Requirements?
|
|
54
|
+
3. research.md → (if exists) Any key technical decisions?
|
|
45
55
|
```
|
|
46
56
|
|
|
47
57
|
### Step 3: Output Brief Summary
|
|
@@ -146,7 +156,7 @@ Ready to continue. What would you like to work on?
|
|
|
146
156
|
|-----------|---------|
|
|
147
157
|
| Context full, need to continue building | `/primer-spec` |
|
|
148
158
|
| Want to add improvement mid-build | `/iterate-spec` |
|
|
149
|
-
| Need full validation | `/
|
|
159
|
+
| Need full validation | `/review-spec` |
|
|
150
160
|
| Check status without loading context | `/status-spec` |
|
|
151
161
|
|
|
152
162
|
---
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# /review-spec
|
|
2
|
+
|
|
3
|
+
Run validation checks and code simplification on a completed implementation.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/review-spec @2025-11-29-stripe-integration
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Pre-computed Context
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Build state for validation
|
|
15
|
+
echo "=== BRANCH ===" && git branch --show-current
|
|
16
|
+
echo "=== STATUS ===" && git status --short
|
|
17
|
+
echo "=== TASKS.MD PROGRESS ===" && grep -A 5 "## Progress" .catalyst/specs/*$ARGUMENTS*/tasks.md 2>/dev/null || echo "No tasks.md"
|
|
18
|
+
echo "=== SPEC STATUS ===" && head -20 .catalyst/specs/*$ARGUMENTS*/spec.md 2>/dev/null || echo "No spec.md"
|
|
19
|
+
echo "=== DIFF STAT VS BASE ===" && git diff --stat main...HEAD 2>/dev/null || echo "No diff from main"
|
|
20
|
+
echo "=== FILES CHANGED ===" && git diff --name-only main...HEAD 2>/dev/null || echo "No changes from main"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
**Invoke skill:** `spec-validation`
|
|
26
|
+
|
|
27
|
+
**Orchestrator:** Arbiter (delegates to Enforcer, Sentinel, Inquisitor, Watcher)
|
|
28
|
+
|
|
29
|
+
**Process skills used:** `verification-before-completion`, `agent-delegation`, `test-driven-development`
|
|
@@ -8,6 +8,19 @@ Check the current status of a spec and sync progress with reality.
|
|
|
8
8
|
/status-spec @2025-11-29-stripe-integration
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Pre-computed Context
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Current git state
|
|
15
|
+
echo "=== BRANCH ===" && git branch --show-current
|
|
16
|
+
echo "=== STATUS ===" && git status --short
|
|
17
|
+
echo "=== DIFF STAT ===" && git diff --stat
|
|
18
|
+
echo "=== RECENT COMMITS ===" && git log --oneline -10
|
|
19
|
+
echo "=== SPEC FILES ===" && ls .catalyst/specs/*$ARGUMENTS*/ 2>/dev/null || echo "No spec found for: $ARGUMENTS"
|
|
20
|
+
echo "=== TASKS.MD ===" && cat .catalyst/specs/*$ARGUMENTS*/tasks.md 2>/dev/null | head -80 || echo "No tasks.md"
|
|
21
|
+
echo "=== SPEC STATUS ===" && head -20 .catalyst/specs/*$ARGUMENTS*/spec.md 2>/dev/null || echo "No spec.md"
|
|
22
|
+
```
|
|
23
|
+
|
|
11
24
|
---
|
|
12
25
|
|
|
13
26
|
## Purpose
|
|
@@ -18,13 +31,15 @@ Resume work on a spec after being away. This command:
|
|
|
18
31
|
3. Syncs tasks.md with reality
|
|
19
32
|
4. Gives you a clear "where we are" summary
|
|
20
33
|
|
|
34
|
+
Use the pre-computed context above — do NOT re-run these commands. Only run additional commands if specific details are missing.
|
|
35
|
+
|
|
21
36
|
---
|
|
22
37
|
|
|
23
38
|
## Workflow
|
|
24
39
|
|
|
25
40
|
### Phase 1: Read Spec State
|
|
26
41
|
|
|
27
|
-
Read all spec files:
|
|
42
|
+
Read all spec files (use pre-computed context first, read full files only if needed):
|
|
28
43
|
- `spec.md` → Feature overview, requirements, status
|
|
29
44
|
- `tasks.md` → Task breakdown, marked progress
|
|
30
45
|
- `research.md` → Context and decisions made
|
|
@@ -32,18 +47,11 @@ Read all spec files:
|
|
|
32
47
|
|
|
33
48
|
### Phase 2: Check Git Reality
|
|
34
49
|
|
|
35
|
-
|
|
50
|
+
Use pre-computed git context. Only run additional commands if needed:
|
|
36
51
|
|
|
37
52
|
```bash
|
|
38
|
-
#
|
|
39
|
-
git status --short
|
|
40
|
-
|
|
41
|
-
# What's the diff for uncommitted work?
|
|
42
|
-
git diff --stat
|
|
43
|
-
|
|
44
|
-
# Recent commits related to this spec
|
|
53
|
+
# Additional detail if needed
|
|
45
54
|
git log --oneline -10 --grep="{slug}"
|
|
46
|
-
git log --oneline -10 -- "src/" "lib/" "app/" # Recent code commits
|
|
47
55
|
```
|
|
48
56
|
|
|
49
57
|
### Phase 3: Reconcile Tasks
|
|
@@ -234,9 +242,9 @@ VALIDATION STATUS
|
|
|
234
242
|
|
|
235
243
|
NEXT STEPS
|
|
236
244
|
----------
|
|
237
|
-
1. Complete validation: /
|
|
245
|
+
1. Complete validation: /review-spec @slug
|
|
238
246
|
2. Review handoff.md when ready
|
|
239
|
-
3.
|
|
247
|
+
3. Commit: /commit-spec @slug
|
|
240
248
|
```
|
|
241
249
|
|
|
242
250
|
---
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse hook: Auto-format files after Edit/Write operations
|
|
3
|
+
# Runs the project's formatter on changed code files.
|
|
4
|
+
# Always exits 0 — formatting is advisory, never blocks.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
FILE_PATH="${1:-}"
|
|
9
|
+
|
|
10
|
+
# Skip if no file path provided or file doesn't exist
|
|
11
|
+
[[ -z "$FILE_PATH" || ! -f "$FILE_PATH" ]] && exit 0
|
|
12
|
+
|
|
13
|
+
# Get file extension
|
|
14
|
+
EXT="${FILE_PATH##*.}"
|
|
15
|
+
|
|
16
|
+
# Skip non-code files
|
|
17
|
+
case "$EXT" in
|
|
18
|
+
md|txt|yaml|yml|json|lock|log|csv|svg|png|jpg|gif|ico|woff|woff2|ttf|eot)
|
|
19
|
+
exit 0
|
|
20
|
+
;;
|
|
21
|
+
esac
|
|
22
|
+
|
|
23
|
+
# Find project root (where package.json or .git lives)
|
|
24
|
+
PROJECT_ROOT="$(cd "$(dirname "$FILE_PATH")" && git rev-parse --show-toplevel 2>/dev/null || echo "")"
|
|
25
|
+
[[ -z "$PROJECT_ROOT" ]] && exit 0
|
|
26
|
+
|
|
27
|
+
# --- Formatter detection (first match wins) ---
|
|
28
|
+
|
|
29
|
+
# Biome
|
|
30
|
+
if [[ -f "$PROJECT_ROOT/biome.json" || -f "$PROJECT_ROOT/biome.jsonc" ]]; then
|
|
31
|
+
if command -v npx &>/dev/null; then
|
|
32
|
+
npx --yes @biomejs/biome format --write "$FILE_PATH" 2>/dev/null || true
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Prettier
|
|
38
|
+
if [[ -f "$PROJECT_ROOT/.prettierrc" || -f "$PROJECT_ROOT/.prettierrc.json" || -f "$PROJECT_ROOT/.prettierrc.js" || -f "$PROJECT_ROOT/.prettierrc.yaml" || -f "$PROJECT_ROOT/.prettierrc.yml" || -f "$PROJECT_ROOT/prettier.config.js" || -f "$PROJECT_ROOT/prettier.config.mjs" ]]; then
|
|
39
|
+
if command -v npx &>/dev/null; then
|
|
40
|
+
npx --yes prettier --write "$FILE_PATH" 2>/dev/null || true
|
|
41
|
+
exit 0
|
|
42
|
+
fi
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Check package.json for prettier as dependency (common case: no .prettierrc but prettier installed)
|
|
46
|
+
if [[ -f "$PROJECT_ROOT/package.json" ]] && grep -q '"prettier"' "$PROJECT_ROOT/package.json" 2>/dev/null; then
|
|
47
|
+
if command -v npx &>/dev/null; then
|
|
48
|
+
npx --yes prettier --write "$FILE_PATH" 2>/dev/null || true
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# --- TypeScript type-check (non-blocking) ---
|
|
54
|
+
case "$EXT" in
|
|
55
|
+
ts|tsx)
|
|
56
|
+
if [[ -f "$PROJECT_ROOT/tsconfig.json" ]] && command -v npx &>/dev/null; then
|
|
57
|
+
npx --yes tsc --noEmit 2>/dev/null || true
|
|
58
|
+
fi
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
|
|
62
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreCompact hook: Auto-save current state to tasks.md before context compaction
|
|
3
|
+
# Ensures /primer-spec always has accurate resume info, even if agents forgot to update.
|
|
4
|
+
# Always exits 0 — state saving should never block compaction.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Find project root
|
|
9
|
+
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "")"
|
|
10
|
+
[[ -z "$PROJECT_ROOT" ]] && exit 0
|
|
11
|
+
|
|
12
|
+
# --- Detect active spec from branch name ---
|
|
13
|
+
BRANCH="$(git branch --show-current 2>/dev/null || echo "")"
|
|
14
|
+
SLUG=""
|
|
15
|
+
|
|
16
|
+
# Extract slug from branch: feat/YYYY-MM-DD-slug or feat/slug
|
|
17
|
+
if [[ "$BRANCH" =~ ^[^/]+/(.+)$ ]]; then
|
|
18
|
+
SLUG="${BASH_REMATCH[1]}"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
[[ -z "$SLUG" ]] && exit 0
|
|
22
|
+
|
|
23
|
+
# --- Find matching tasks.md ---
|
|
24
|
+
TASKS_FILE=""
|
|
25
|
+
|
|
26
|
+
# Try exact match first
|
|
27
|
+
for dir in "$PROJECT_ROOT"/.catalyst/specs/*-"$SLUG"; do
|
|
28
|
+
if [[ -f "$dir/tasks.md" ]]; then
|
|
29
|
+
TASKS_FILE="$dir/tasks.md"
|
|
30
|
+
break
|
|
31
|
+
fi
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
# Try broader match if exact didn't work
|
|
35
|
+
if [[ -z "$TASKS_FILE" ]]; then
|
|
36
|
+
for dir in "$PROJECT_ROOT"/.catalyst/specs/*"$SLUG"*; do
|
|
37
|
+
if [[ -f "$dir/tasks.md" ]]; then
|
|
38
|
+
TASKS_FILE="$dir/tasks.md"
|
|
39
|
+
break
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
[[ -z "$TASKS_FILE" ]] && exit 0
|
|
45
|
+
|
|
46
|
+
# --- Build state snapshot ---
|
|
47
|
+
TIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
|
|
48
|
+
GIT_STATUS="$(git status --short 2>/dev/null | head -20 || echo "unknown")"
|
|
49
|
+
MODIFIED_COUNT="$(git status --short 2>/dev/null | wc -l | tr -d ' ' || echo "0")"
|
|
50
|
+
|
|
51
|
+
STATE_BLOCK="**Phase:** (check Progress table above)
|
|
52
|
+
**Timestamp:** $TIMESTAMP
|
|
53
|
+
**Branch:** $BRANCH
|
|
54
|
+
**Modified files:** $MODIFIED_COUNT
|
|
55
|
+
**Auto-saved:** Yes (PreCompact hook)
|
|
56
|
+
|
|
57
|
+
\`\`\`
|
|
58
|
+
$GIT_STATUS
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
> Resume with \`/primer-spec @$SLUG\` in a new conversation."
|
|
62
|
+
|
|
63
|
+
# --- Update Current Session section ---
|
|
64
|
+
# Replace existing Current Session content, or append if missing
|
|
65
|
+
if grep -q "^## Current Session" "$TASKS_FILE" 2>/dev/null; then
|
|
66
|
+
# Find the line number of "## Current Session" and the next "##" heading
|
|
67
|
+
SESSION_LINE="$(grep -n "^## Current Session" "$TASKS_FILE" | head -1 | cut -d: -f1)"
|
|
68
|
+
NEXT_HEADING="$(tail -n +"$((SESSION_LINE + 1))" "$TASKS_FILE" | grep -n "^## " | head -1 | cut -d: -f1)"
|
|
69
|
+
|
|
70
|
+
if [[ -n "$NEXT_HEADING" ]]; then
|
|
71
|
+
# There's a section after Current Session — replace between them
|
|
72
|
+
END_LINE="$((SESSION_LINE + NEXT_HEADING - 1))"
|
|
73
|
+
{
|
|
74
|
+
head -n "$SESSION_LINE" "$TASKS_FILE"
|
|
75
|
+
echo ""
|
|
76
|
+
echo -e "$STATE_BLOCK"
|
|
77
|
+
echo ""
|
|
78
|
+
tail -n +"$END_LINE" "$TASKS_FILE"
|
|
79
|
+
} > "${TASKS_FILE}.tmp" && mv "${TASKS_FILE}.tmp" "$TASKS_FILE"
|
|
80
|
+
else
|
|
81
|
+
# Current Session is the last section — replace to end
|
|
82
|
+
{
|
|
83
|
+
head -n "$SESSION_LINE" "$TASKS_FILE"
|
|
84
|
+
echo ""
|
|
85
|
+
echo -e "$STATE_BLOCK"
|
|
86
|
+
} > "${TASKS_FILE}.tmp" && mv "${TASKS_FILE}.tmp" "$TASKS_FILE"
|
|
87
|
+
fi
|
|
88
|
+
else
|
|
89
|
+
# No Current Session section — append it
|
|
90
|
+
{
|
|
91
|
+
echo ""
|
|
92
|
+
echo "## Current Session"
|
|
93
|
+
echo ""
|
|
94
|
+
echo -e "$STATE_BLOCK"
|
|
95
|
+
} >> "$TASKS_FILE"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Coding Standards
|
|
2
|
+
|
|
3
|
+
These rules apply to ALL code generation, regardless of which skill is active.
|
|
4
|
+
|
|
5
|
+
## Language
|
|
6
|
+
|
|
7
|
+
- All generated artifacts MUST be in English (code, comments, docs, commit messages)
|
|
8
|
+
- Communicate with the user in their preferred language
|
|
9
|
+
|
|
10
|
+
## File Hygiene
|
|
11
|
+
|
|
12
|
+
- Keep files under 300 lines — split if larger
|
|
13
|
+
- No deep nesting (max 3 levels of indentation for logic)
|
|
14
|
+
- One concept per file — don't mix unrelated concerns
|
|
15
|
+
|
|
16
|
+
## Quality
|
|
17
|
+
|
|
18
|
+
- Write minimal code that solves the current requirement
|
|
19
|
+
- Don't add features, abstractions, or config that wasn't requested
|
|
20
|
+
- Prefer clarity over cleverness
|
|
21
|
+
- Delete dead code — don't comment it out
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Git Workflow Rules
|
|
2
|
+
|
|
3
|
+
These rules apply to ALL git operations, regardless of which skill is active.
|
|
4
|
+
|
|
5
|
+
## Branch Naming
|
|
6
|
+
|
|
7
|
+
- Feature branches: `{branch_prefix}/{spec-slug}` (e.g., `feat/2026-01-11-user-auth`)
|
|
8
|
+
- Read `branch_prefix` from `.catalyst/main/project-config.yaml`
|
|
9
|
+
- Never commit directly to protected branches (`main`, `master`)
|
|
10
|
+
|
|
11
|
+
## Commit Messages
|
|
12
|
+
|
|
13
|
+
- Red phase: `test({scope}): write failing tests for {spec}`
|
|
14
|
+
- Green phase: `feat({scope}): implement {spec}`
|
|
15
|
+
- Bug fixes: `fix({scope}): description`
|
|
16
|
+
- Refactors: `refactor({scope}): description`
|
|
17
|
+
- Keep subject line under 72 characters
|
|
18
|
+
- Use imperative mood ("add", not "added")
|
|
19
|
+
|
|
20
|
+
## Operations
|
|
21
|
+
|
|
22
|
+
- Always check `git status` before destructive operations
|
|
23
|
+
- Never force-push to shared branches without user confirmation
|
|
24
|
+
- Prefer creating new commits over amending published ones
|
|
25
|
+
- Stage specific files — avoid `git add -A` which may catch secrets
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Security Rules
|
|
2
|
+
|
|
3
|
+
These rules apply to ALL actions, regardless of which skill is active.
|
|
4
|
+
|
|
5
|
+
## Secrets
|
|
6
|
+
|
|
7
|
+
- **NEVER** commit `.env`, `.env.*`, credentials, API keys, or tokens
|
|
8
|
+
- **NEVER** hardcode secrets in source code — use environment variables
|
|
9
|
+
- Verify `.gitignore` includes `.env*` before any git operations
|
|
10
|
+
- If a secret is accidentally staged, **unstage immediately** and rotate the key
|
|
11
|
+
|
|
12
|
+
## Dependencies
|
|
13
|
+
|
|
14
|
+
- Do not install packages with known critical CVEs
|
|
15
|
+
- Prefer well-maintained packages with active security practices
|
|
16
|
+
- Pin major versions in production dependencies
|
|
17
|
+
|
|
18
|
+
## Code
|
|
19
|
+
|
|
20
|
+
- Sanitize all user input at system boundaries
|
|
21
|
+
- Use parameterized queries — never string-concatenate SQL
|
|
22
|
+
- Escape output to prevent XSS
|
|
23
|
+
- Validate file paths to prevent traversal attacks
|
|
@@ -28,7 +28,7 @@ Orchestrate the full build workflow: task breakdown, test writing, foundation, c
|
|
|
28
28
|
├── spec.md # Already exists from /catalyze-spec
|
|
29
29
|
├── research.md # Already exists from /catalyze-spec
|
|
30
30
|
├── tasks.md # Forger creates (this phase)
|
|
31
|
-
├── validation.md # Arbiter creates (in /
|
|
31
|
+
├── validation.md # Arbiter creates (in /review-spec)
|
|
32
32
|
├── handoff.md # Updated throughout
|
|
33
33
|
└── assets/
|
|
34
34
|
```
|
|
@@ -144,6 +144,9 @@ Only AFTER this commit exists may implementation begin.
|
|
|
144
144
|
No commit = no implementation. No exceptions.
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
+
> **Context checkpoint:** If context is getting long, compact now. All state is in `tasks.md`.
|
|
148
|
+
> Run `/primer-spec @{slug}` in a new conversation to resume.
|
|
149
|
+
|
|
147
150
|
- Every task has at least one test
|
|
148
151
|
- All tests executed
|
|
149
152
|
- All tests FAIL (for the right reasons — missing feature, not import errors)
|
|
@@ -151,6 +154,9 @@ No commit = no implementation. No exceptions.
|
|
|
151
154
|
|
|
152
155
|
### Phase 3-4: Foundation & Contracts
|
|
153
156
|
|
|
157
|
+
> **Context checkpoint:** If context is getting long, compact now. All state is in `tasks.md`.
|
|
158
|
+
> Run `/primer-spec @{slug}` in a new conversation to resume.
|
|
159
|
+
|
|
154
160
|
Spawn Alchemist (foundation) → WAIT → Spawn Smith (contracts) → WAIT
|
|
155
161
|
|
|
156
162
|
### Phase 5: Parallel Implementation
|
|
@@ -178,8 +184,14 @@ COMMIT: "feat({scope}): implement {spec}"
|
|
|
178
184
|
Only AFTER this commit exists may integration begin.
|
|
179
185
|
```
|
|
180
186
|
|
|
187
|
+
> **Context checkpoint:** If context is getting long, compact now. All state is in `tasks.md`.
|
|
188
|
+
> Run `/primer-spec @{slug}` in a new conversation to resume.
|
|
189
|
+
|
|
181
190
|
### Phase 6: Integration
|
|
182
191
|
|
|
192
|
+
> **Context checkpoint:** If context is getting long, compact now. All state is in `tasks.md`.
|
|
193
|
+
> Run `/primer-spec @{slug}` in a new conversation to resume.
|
|
194
|
+
|
|
183
195
|
Spawn Enforcer for cross-boundary integration tests.
|
|
184
196
|
|
|
185
197
|
## Implementation Rules
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Spec Approval
|
|
2
2
|
|
|
3
3
|
> **When to invoke:** When accepting an implementation and archiving the spec.
|
|
4
|
-
> **Invoked by:** `/
|
|
4
|
+
> **Invoked by:** `/commit-spec` command.
|
|
5
5
|
|
|
6
6
|
## Purpose
|
|
7
7
|
|
|
@@ -15,10 +15,10 @@ Final verification, git commit, spec archival, self-documentation (propagate lea
|
|
|
15
15
|
## Prerequisites — HARD GATES
|
|
16
16
|
|
|
17
17
|
> **This skill is the FINAL step in the spec lifecycle.** It runs ONLY after build and validation are complete.
|
|
18
|
-
> **Flow:** `/catalyze-spec` → `/build-spec` → `/
|
|
18
|
+
> **Flow:** `/catalyze-spec` → `/build-spec` → `/review-spec` → **`/commit-spec`** (you are here)
|
|
19
19
|
>
|
|
20
20
|
> If the spec has not been built yet, STOP and tell the user to run `/build-spec` first.
|
|
21
|
-
> If the spec has not been validated yet, STOP and tell the user to run `/
|
|
21
|
+
> If the spec has not been validated yet, STOP and tell the user to run `/review-spec` first.
|
|
22
22
|
|
|
23
23
|
- `/build-spec` must have been completed (tasks.md exists with completed tasks)
|
|
24
24
|
- Validation must be complete (`validation.md` must show all checks passed)
|
|
@@ -178,4 +178,4 @@ Next steps:
|
|
|
178
178
|
- Or /iterate-spec if you want changes first
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
**IMPORTANT: Do NOT suggest `/
|
|
181
|
+
**IMPORTANT: Do NOT suggest `/commit-spec` after spec shaping.** `/commit-spec` is only for committing a fully built and validated implementation — it is the FINAL step, not a plan-approval step. The correct flow is: `/catalyze-spec` → `/build-spec` → `/review-spec` → `/commit-spec`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Spec Validation
|
|
2
2
|
|
|
3
3
|
> **When to invoke:** When running validation checks on a completed implementation.
|
|
4
|
-
> **Invoked by:** `/
|
|
4
|
+
> **Invoked by:** `/review-spec` command.
|
|
5
5
|
> **Orchestrator:** Arbiter agent.
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
@@ -76,10 +76,13 @@ Spawn all Guardians in parallel:
|
|
|
76
76
|
- Test user flows
|
|
77
77
|
- Capture screenshots on failure
|
|
78
78
|
|
|
79
|
-
**Inquisitor** (Code Quality):
|
|
79
|
+
**Inquisitor** (Code Quality + Simplification):
|
|
80
80
|
- Run linters
|
|
81
81
|
- Code review checks
|
|
82
82
|
- Documentation gaps
|
|
83
|
+
- **Code simplification suggestions** (unnecessary abstractions, over-engineering, dead code, verbose patterns)
|
|
84
|
+
- Simplifications must NOT change behavior — only structure
|
|
85
|
+
- Provide before/after snippets for each suggestion
|
|
83
86
|
|
|
84
87
|
**Watcher** (Security):
|
|
85
88
|
- Dependency audit
|
|
@@ -126,8 +129,9 @@ If all validation passes, create handoff.md with:
|
|
|
126
129
|
- Total: N, Passing: N
|
|
127
130
|
|
|
128
131
|
## Quality Checks
|
|
129
|
-
### Lint (Inquisitor)
|
|
130
|
-
- Status: PASS/FAIL, Errors: N, Warnings: N
|
|
132
|
+
### Lint & Simplification (Inquisitor)
|
|
133
|
+
- Lint Status: PASS/FAIL, Errors: N, Warnings: N
|
|
134
|
+
- Simplification Opportunities: N found
|
|
131
135
|
|
|
132
136
|
### Security (Watcher)
|
|
133
137
|
- Dependencies: status
|
|
@@ -153,7 +157,7 @@ If all validation passes, create handoff.md with:
|
|
|
153
157
|
```
|
|
154
158
|
Validation complete!
|
|
155
159
|
Status: READY FOR APPROVAL
|
|
156
|
-
Next: /
|
|
160
|
+
Next: /commit-spec @slug
|
|
157
161
|
```
|
|
158
162
|
|
|
159
163
|
### TDD Failure
|
|
@@ -167,5 +171,5 @@ Action: Return to /build-spec and follow TDD process
|
|
|
167
171
|
```
|
|
168
172
|
Validation failed!
|
|
169
173
|
Failed Checks: [details]
|
|
170
|
-
Action: Fix issues and re-run /
|
|
174
|
+
Action: Fix issues and re-run /review-spec
|
|
171
175
|
```
|
|
@@ -44,8 +44,8 @@ Skills tell you HOW. User instructions tell you WHAT.
|
|
|
44
44
|
| **spec-shaping** | `.claude/skills/spec-shaping/SKILL.md` | `/catalyze-spec` — shaping a new specification |
|
|
45
45
|
| **build-orchestration** | `.claude/skills/build-orchestration/SKILL.md` | `/build-spec` — implementing a specification |
|
|
46
46
|
| **spec-iteration** | `.claude/skills/spec-iteration/SKILL.md` | `/iterate-spec` — updating and continuing a build |
|
|
47
|
-
| **spec-validation** | `.claude/skills/spec-validation/SKILL.md` | `/
|
|
48
|
-
| **spec-approval** | `.claude/skills/spec-approval/SKILL.md` | `/
|
|
47
|
+
| **spec-validation** | `.claude/skills/spec-validation/SKILL.md` | `/review-spec` — quality checks on implementation |
|
|
48
|
+
| **spec-approval** | `.claude/skills/spec-approval/SKILL.md` | `/commit-spec` — final commit and archival |
|
|
49
49
|
| **project-initialization** | `.claude/skills/project-initialization/SKILL.md` | `/catalyze-project` — setting up a new project |
|
|
50
50
|
| **task-building** | `.claude/skills/task-building/SKILL.md` | `/build-task` — building a single task (brownfield) |
|
|
51
51
|
| **spec-update** | `.claude/skills/spec-update/SKILL.md` | `/update-spec` — modifying an existing spec |
|
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ npx catalyst-os # Install to your project
|
|
|
12
12
|
/catalyze-spec "description" # Shape a feature specification
|
|
13
13
|
/build-spec @spec-name # Implement with TDD
|
|
14
14
|
/iterate-spec @spec-name "improvement" # Add improvements mid-build
|
|
15
|
-
/
|
|
16
|
-
/
|
|
15
|
+
/review-spec @spec-name # Run quality checks
|
|
16
|
+
/commit-spec @spec-name # Accept and archive
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
---
|
|
@@ -105,8 +105,8 @@ Without this, skills are optional documentation. With it, they're mandatory proc
|
|
|
105
105
|
| `spec-shaping` | `/catalyze-spec` | Shape feature requests into specifications |
|
|
106
106
|
| `build-orchestration` | `/build-spec` | DAG-based TDD implementation |
|
|
107
107
|
| `spec-iteration` | `/iterate-spec` | Update and continue mid-build |
|
|
108
|
-
| `spec-validation` | `/
|
|
109
|
-
| `spec-approval` | `/
|
|
108
|
+
| `spec-validation` | `/review-spec` | Quality checks via Guardian agents |
|
|
109
|
+
| `spec-approval` | `/commit-spec` | Final verification and archival |
|
|
110
110
|
| `project-initialization` | `/catalyze-project` | Workspace detection + foundation docs |
|
|
111
111
|
| `task-building` | `/build-task` | Single task (brownfield) |
|
|
112
112
|
| `spec-update` | `/update-spec` | Modify spec during planning phase |
|
|
@@ -173,10 +173,10 @@ Guardians (Quality)
|
|
|
173
173
|
```
|
|
174
174
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
175
175
|
│ │ │ │ │ │ │ │
|
|
176
|
-
│ CATALYZE │────>│ BUILD │────>│
|
|
176
|
+
│ CATALYZE │────>│ BUILD │────>│ REVIEW │────>│ COMMIT │
|
|
177
177
|
│ │ │ │ │ │ │ │
|
|
178
|
-
│ /catalyze- │ │ /build-spec │ │ /
|
|
179
|
-
│ spec │ │ │ │
|
|
178
|
+
│ /catalyze- │ │ /build-spec │ │ /review-spec │ │ /commit-spec │
|
|
179
|
+
│ spec │ │ │ │ │ │ │
|
|
180
180
|
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
|
|
181
181
|
│ │ │ │
|
|
182
182
|
v v v v
|
|
@@ -209,9 +209,9 @@ Guardians (Quality)
|
|
|
209
209
|
| `/iterate-spec @slug "idea"` | Add improvements mid-build | Updated spec + tasks, continues building |
|
|
210
210
|
| `/primer-spec @slug` | Restore context (new conversation) | Brief status summary |
|
|
211
211
|
| `/build-task "description"` | Modify existing code | task.md in .catalyst/tasks/ |
|
|
212
|
-
| `/
|
|
213
|
-
| `/
|
|
214
|
-
| `/
|
|
212
|
+
| `/review-spec @slug` | Quality checks | validation.md, handoff.md |
|
|
213
|
+
| `/commit-spec @slug` | Finalize | Commit + Archive |
|
|
214
|
+
| `/discard-spec @slug "reason"` | Discard implementation | Status: REJECTED |
|
|
215
215
|
| `/status-spec @slug` | Check progress | Current status |
|
|
216
216
|
| `/update-spec @slug "change"` | Modify spec (planning phase) | Updated spec.md |
|
|
217
217
|
| `/mission` | Create/update mission.md | mission.md |
|
|
@@ -296,7 +296,7 @@ Enforcer -> Builders │ TDD: tests before code
|
|
|
296
296
|
|
|
297
297
|
## Pattern Library
|
|
298
298
|
|
|
299
|
-
Reusable implementation patterns extracted from completed specs via `/
|
|
299
|
+
Reusable implementation patterns extracted from completed specs via `/commit-spec`.
|
|
300
300
|
|
|
301
301
|
**Location:** `.catalyst/library/`
|
|
302
302
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "catalyst-os",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"postinstall": "node .catalyst/bin/install.js"
|
|
5
|
+
"postinstall": "node .catalyst/bin/install.js",
|
|
6
|
+
"validate": "node .catalyst/bin/validate-artifacts.js"
|
|
6
7
|
},
|
|
7
8
|
"description": "AI-native spec-driven development framework for Claude Code",
|
|
8
9
|
"bin": {
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# /approve-spec
|
|
2
|
-
|
|
3
|
-
Accept a **fully built and validated** implementation — commit, archive, and propagate learnings.
|
|
4
|
-
|
|
5
|
-
> **Lifecycle position:** This is the FINAL step. Only use after `/build-spec` and `/validate-spec` have completed successfully.
|
|
6
|
-
>
|
|
7
|
-
> **Flow:** `/catalyze-spec` → `/build-spec` → `/validate-spec` → **`/approve-spec`**
|
|
8
|
-
>
|
|
9
|
-
> **This is NOT for approving a spec/plan before building.** There is no "approve plan" step — after catalyzing, you go straight to `/build-spec`.
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
/approve-spec @2025-11-29-stripe-integration
|
|
15
|
-
/approve-spec @2025-11-29-stripe-integration "Great work!"
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
**Invoke skill:** `spec-approval`
|
|
21
|
-
|
|
22
|
-
**Process skills used:** `verification-before-completion`, `agent-delegation`
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# /validate-spec
|
|
2
|
-
|
|
3
|
-
Run validation checks on a completed implementation.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
/validate-spec @2025-11-29-stripe-integration
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
**Invoke skill:** `spec-validation`
|
|
14
|
-
|
|
15
|
-
**Orchestrator:** Arbiter (delegates to Enforcer, Sentinel, Inquisitor, Watcher)
|
|
16
|
-
|
|
17
|
-
**Process skills used:** `verification-before-completion`, `agent-delegation`, `test-driven-development`
|