@esoteric-logic/praxis-harness 1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +192 -0
  3. package/base/CLAUDE.md +148 -0
  4. package/base/commands/context-reset.md +72 -0
  5. package/base/commands/debug.md +63 -0
  6. package/base/commands/discover.md +49 -0
  7. package/base/commands/gsd-discuss.md +53 -0
  8. package/base/commands/gsd-execute.md +60 -0
  9. package/base/commands/gsd-verify.md +78 -0
  10. package/base/commands/kit.md +62 -0
  11. package/base/commands/plan.md +91 -0
  12. package/base/commands/ralph.md +110 -0
  13. package/base/commands/review.md +81 -0
  14. package/base/commands/risk.md +53 -0
  15. package/base/commands/ship.md +74 -0
  16. package/base/commands/spec.md +121 -0
  17. package/base/commands/standup.md +57 -0
  18. package/base/rules/architecture.md +51 -0
  19. package/base/rules/azure.md +90 -0
  20. package/base/rules/code-quality.md +65 -0
  21. package/base/rules/coding.md +139 -0
  22. package/base/rules/communication.md +69 -0
  23. package/base/rules/context-management.md +136 -0
  24. package/base/rules/execution-loop.md +84 -0
  25. package/base/rules/git-workflow.md +51 -0
  26. package/base/rules/github-actions.md +48 -0
  27. package/base/rules/powershell.md +72 -0
  28. package/base/rules/profile.md +31 -0
  29. package/base/rules/security.md +40 -0
  30. package/base/rules/terraform.md +48 -0
  31. package/base/rules/vault.md +134 -0
  32. package/base/skills/code-gc/SKILL.md +205 -0
  33. package/base/skills/code-simplifier/SKILL.md +132 -0
  34. package/base/skills/prd-writer/SKILL.md +108 -0
  35. package/base/skills/prd-writer/references/prd-template.md +22 -0
  36. package/base/skills/pre-commit-lint/SKILL.md +71 -0
  37. package/base/skills/scaffold-exist/SKILL.md +85 -0
  38. package/base/skills/scaffold-new/SKILL.md +177 -0
  39. package/base/skills/scaffold-new/references/claude-progress-template.json +24 -0
  40. package/base/skills/scaffold-new/references/gitignore-template.txt +65 -0
  41. package/base/skills/scaffold-new/references/repo-CLAUDE-md-template.md +87 -0
  42. package/base/skills/scaffold-new/references/vault-index-template.md +31 -0
  43. package/base/skills/scaffold-new/references/vault-learnings-template.md +21 -0
  44. package/base/skills/scaffold-new/references/vault-status-template.md +21 -0
  45. package/base/skills/scaffold-new/references/vault-tasks-template.md +20 -0
  46. package/base/skills/session-retro/SKILL.md +146 -0
  47. package/base/skills/subagent-review/SKILL.md +126 -0
  48. package/base/skills/vault-gc/SKILL.md +93 -0
  49. package/base/skills/verify-app/SKILL.md +156 -0
  50. package/bin/praxis.js +385 -0
  51. package/kits/infrastructure/KIT.md +66 -0
  52. package/kits/infrastructure/commands/infra-apply.md +44 -0
  53. package/kits/infrastructure/commands/infra-compliance.md +65 -0
  54. package/kits/infrastructure/commands/infra-drift.md +45 -0
  55. package/kits/infrastructure/commands/infra-plan.md +45 -0
  56. package/kits/infrastructure/install.sh +43 -0
  57. package/kits/infrastructure/rules/infrastructure.md +82 -0
  58. package/kits/infrastructure/teardown.sh +14 -0
  59. package/kits/web-designer/KIT.md +76 -0
  60. package/kits/web-designer/commands/web-audit.md +67 -0
  61. package/kits/web-designer/commands/web-component.md +54 -0
  62. package/kits/web-designer/commands/web-init.md +42 -0
  63. package/kits/web-designer/commands/web-tokens-sync.md +49 -0
  64. package/kits/web-designer/install.sh +41 -0
  65. package/kits/web-designer/rules/web-design.md +79 -0
  66. package/kits/web-designer/teardown.sh +26 -0
  67. package/package.json +28 -0
  68. package/scripts/health-check.sh +160 -0
  69. package/scripts/lint-harness.sh +195 -0
  70. package/scripts/onboard-mcp.sh +326 -0
  71. package/scripts/update.sh +88 -0
  72. package/templates/_index.md +33 -0
  73. package/templates/adr.md +28 -0
  74. package/templates/claude-progress.json +24 -0
  75. package/templates/plan.md +46 -0
  76. package/templates/project-index.md +31 -0
  77. package/templates/session-note.md +21 -0
  78. package/templates/status.md +27 -0
  79. package/templates/tasks.md +27 -0
@@ -0,0 +1,205 @@
1
+ ---
2
+ name: code-gc
3
+ disable-model-invocation: true
4
+ description: Detect code entropy in the current repo. Dead code, test debt, stale
5
+ TODOs, oversized functions, commented-out blocks, unused deps. Two modes:
6
+ lightweight (called by session-retro) and full audit (manual /code-gc).
7
+ Never auto-deletes or auto-fixes. Side-effect skill — never auto-triggers.
8
+ allowed-tools: Bash, Read, Write
9
+ ---
10
+
11
+ # code-gc Skill
12
+
13
+ ## Vault Path Resolution
14
+ Read vault_path from `~/.claude/praxis.config.json`.
15
+ Detect current project by matching CWD to `local_path` in vault `_index.md`.
16
+
17
+ ## Two Modes
18
+
19
+ | Mode | Trigger | Scope | Output |
20
+ |------|---------|-------|--------|
21
+ | **Lightweight** | Called by `session-retro` Phase 6b | TODOs + test debt delta only | One line or silence |
22
+ | **Full Audit** | Manual `/code-gc` | All 6 entropy checks | Prioritized report, offer to write vault |
23
+
24
+ ---
25
+
26
+ ## Mode A — Lightweight (session-retro)
27
+
28
+ Run only these two checks against the current session's diff:
29
+
30
+ ```bash
31
+ # New TODOs/FIXMEs introduced this session
32
+ git diff HEAD -- '*.ts' '*.py' '*.go' '*.js' '*.rs' '*.rb' | \
33
+ grep "^+" | grep -cE "(TODO|FIXME|HACK|XXX)"
34
+
35
+ # Production files touched without corresponding test file touched
36
+ git diff --name-only HEAD | grep -vE "(test|spec|__tests__|_test)" | \
37
+ grep -E "\.(ts|py|go|js|rs|rb)$"
38
+ ```
39
+
40
+ Output rules:
41
+ - 0 TODOs added, test files touched: **silent**
42
+ - TODOs added OR prod files touched without tests: `⚠ code-gc: {n} TODOs added, {n} prod files touched without tests`
43
+ - Never block. Exit 0 always.
44
+
45
+ ---
46
+
47
+ ## Mode B — Full Audit
48
+
49
+ ### Check 1: Dead Code
50
+ ```bash
51
+ # TODOs/FIXMEs with age
52
+ rg "(TODO|FIXME|HACK|XXX)" --line-number --glob "!*.lock" . | head -50
53
+ # For each hit: git blame to get age
54
+
55
+ # Commented-out code blocks (language-agnostic)
56
+ rg --multiline "(^\s*(#|//|--)\s*(def |function |class |const |let |var |func ))"
57
+ ```
58
+ Flag:
59
+ - CRITICAL: TODO older than 90 days in a production path
60
+ - HIGH: Commented-out function/class definition
61
+ - MEDIUM: TODO 30–90 days old
62
+
63
+ ### Check 2: Test Debt
64
+ ```bash
65
+ # Find production source files
66
+ find . -type f \( -name '*.ts' -o -name '*.py' -o -name '*.go' -o -name '*.js' \) \
67
+ -not -path '*/test*' -not -path '*/spec*' -not -path '*/node_modules*' \
68
+ -not -path '*/__tests__*'
69
+
70
+ # For each: check if a corresponding test file exists
71
+ # ts: src/foo.ts → check src/foo.test.ts, src/foo.spec.ts, test/foo.test.ts
72
+ # py: foo.py → check test_foo.py, tests/test_foo.py
73
+ # go: foo.go → check foo_test.go
74
+ ```
75
+ Flag:
76
+ - CRITICAL: Production file with no test file, NOT marked spike/prototype in status.md
77
+ - MEDIUM: Production file with no test, IS marked spike (test debt acknowledged)
78
+
79
+ Also check `status.md` for `## Test Debt` section — report any items there that
80
+ have been stale for >30 days.
81
+
82
+ ### Check 3: Oversized Functions
83
+ ```bash
84
+ # Count lines between function definitions (approximate)
85
+ # TypeScript/JavaScript
86
+ rg --line-number "^(export\s+)?(async\s+)?function |^\s+(async\s+)?[a-zA-Z]+\s*\(" \
87
+ --glob '*.ts' --glob '*.js'
88
+ # Python
89
+ rg --line-number "^def |^ def " --glob '*.py'
90
+ # Go
91
+ rg --line-number "^func " --glob '*.go'
92
+ ```
93
+ For each match: count lines to next same-indent definition.
94
+ Flag:
95
+ - HIGH: >100 lines
96
+ - MEDIUM: 50–100 lines
97
+
98
+ ### Check 4: Unused Dependencies
99
+ ```bash
100
+ # Node/npm
101
+ if [ -f package.json ]; then
102
+ # declared deps vs. actual imports
103
+ node_deps=$(jq -r '.dependencies // {} | keys[]' package.json 2>/dev/null)
104
+ for dep in $node_deps; do
105
+ rg "require\(['\"]}$dep|from ['\"]$dep" --quiet || echo "UNUSED: $dep"
106
+ done
107
+ fi
108
+
109
+ # Python
110
+ if [ -f requirements.txt ]; then
111
+ while read pkg; do
112
+ name=$(echo $pkg | sed 's/[>=<].*//' | tr '[:upper:]' '[:lower:]')
113
+ rg -i "import $name|from $name" --quiet || echo "UNUSED: $pkg"
114
+ done < requirements.txt
115
+ fi
116
+
117
+ # Go
118
+ if [ -f go.mod ]; then
119
+ go mod tidy -e 2>&1 | grep "^unused"
120
+ fi
121
+ ```
122
+ Flag:
123
+ - MEDIUM: Declared dependency with no import found
124
+
125
+ ### Check 5: Orphan Files
126
+ ```bash
127
+ # Files not touched in >180 days in an active project
128
+ git log --diff-filter=M --name-only --format="" --since="180 days ago" | sort -u > /tmp/recent_files
129
+ find . -type f \( -name '*.ts' -o -name '*.py' -o -name '*.go' \) \
130
+ -not -path '*/node_modules*' > /tmp/all_source
131
+ comm -23 <(sort /tmp/all_source) /tmp/recent_files
132
+ ```
133
+ Flag:
134
+ - MEDIUM: Source file not touched in 180+ days in an active project
135
+
136
+ ### Check 6: Stale Comments
137
+ ```bash
138
+ # Comments on lines adjacent to recently changed code that are >90 days old
139
+ # For each comment line in staged/recent changes:
140
+ git log --since='90 days ago' --diff-filter=M -p -- '*.ts' '*.py' '*.go' | \
141
+ grep "^+.*(//)|(#)" | head -20
142
+ ```
143
+ Flag:
144
+ - LOW: Comments that describe WHAT the code does (heuristic match against adjacent code)
145
+
146
+ ---
147
+
148
+ ## Report Format
149
+
150
+ ```
151
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
152
+ CODE GC — {project-slug} {today_date}
153
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
154
+
155
+ CRITICAL ({n})
156
+ ✗ [test-debt] src/auth/login.ts — production path, 0 tests, not marked spike
157
+ ✗ [dead-code] utils/legacy.ts — TODO age 94 days (line 88)
158
+
159
+ HIGH ({n})
160
+ ✗ [oversized] api/handler.go:ProcessRequest — 143 lines
161
+ ✗ [commented-code] services/payment.py:44 — commented-out function definition
162
+
163
+ MEDIUM ({n})
164
+ ⚠ [todo-debt] 14 TODOs — oldest: 47 days (billing/invoice.ts:88)
165
+ ⚠ [unused-dep] "lodash" declared in package.json, never imported
166
+ ⚠ [orphan-file] src/utils/old-formatter.ts — not touched 210 days
167
+
168
+ LOW ({n})
169
+ — [stale-comment] api/routes.ts:22 — comment describes WHAT not WHY
170
+
171
+ CLEAN
172
+ ✓ Test coverage: all production paths have tests
173
+ ✓ No commented-out code blocks
174
+ ✓ All deps used
175
+
176
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
177
+ {n} findings | {n} clean
178
+ code-gc never auto-fixes — act on findings manually
179
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
180
+ ```
181
+
182
+ After report, offer:
183
+ 1. Write findings to `{vault_path}/specs/code-gc-{YYYY-MM-DD}.md`
184
+ 2. Add CRITICAL + HIGH items as tasks to `{vault_path}/tasks.md`
185
+ 3. Address a specific finding now
186
+
187
+ Do NOT auto-remediate. Always ask first.
188
+
189
+ ---
190
+
191
+ ## Error Handling
192
+
193
+ | Condition | Action |
194
+ |-----------|--------|
195
+ | Not a git repo | STOP. Report — code-gc requires git history for age detection |
196
+ | No source files found | Report clean, note stack not detected |
197
+ | Dep check tool missing | Skip that check, note in report |
198
+ | `go mod tidy` fails | Skip Go dep check, note in report |
199
+ | Project not in vault | Run checks, skip vault write offer |
200
+
201
+ ---
202
+
203
+ ## Removal Condition
204
+ Remove when static analysis tooling (Semgrep, SonarQube, or equivalent) is wired
205
+ into the pre-commit hook and covers all six entropy categories with automated reporting.
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: code-simplifier
3
+ disable-model-invocation: true
4
+ description: Post-implementation code simplification. Launches a subagent to review
5
+ recent changes for unnecessary complexity, over-abstraction, and opportunities to
6
+ simplify. Runs after any implementation phase. Side-effect skill — never auto-triggers.
7
+ allowed-tools: Bash, Read, Edit
8
+ ---
9
+
10
+ # code-simplifier Skill
11
+
12
+ ## Vault Path Resolution
13
+ Read vault_path from `~/.claude/praxis.config.json`.
14
+ Detect current project by matching CWD to `local_path` in vault `_index.md`.
15
+
16
+ ## DONE-WHEN
17
+ - [ ] Diff analyzed by isolated subagent
18
+ - [ ] Simplification opportunities identified and categorized
19
+ - [ ] User-approved changes applied
20
+ - [ ] No functional regressions (tests pass after changes)
21
+
22
+ ## NON-GOALS
23
+ - Does not add features or change behavior
24
+ - Does not refactor architecture — only simplifies within existing structure
25
+ - Does not touch files outside the recent diff
26
+ - Does not run without user reviewing proposed changes
27
+
28
+ ---
29
+
30
+ ## Phase 1 — Determine Scope
31
+
32
+ Determine what to simplify:
33
+ - Default: `git diff HEAD~1` (last commit)
34
+ - Accept: `HEAD~N`, specific SHA, or `staged`
35
+ - If diff is empty: "Nothing to simplify." Exit.
36
+ - If diff >2000 lines: warn and ask to narrow scope
37
+
38
+ ## Phase 2 — Launch Subagent
39
+
40
+ Launch a subagent with ONLY these inputs (zero conversation history):
41
+
42
+ ```
43
+ You are a code simplification expert. Your only goal is to make this code
44
+ simpler, more readable, and more maintainable WITHOUT changing behavior.
45
+
46
+ ## Diff to simplify
47
+ {the diff}
48
+
49
+ ## Project conventions (if available)
50
+ {contents of project CLAUDE.md}
51
+
52
+ ## Review for these simplification patterns:
53
+
54
+ 1. **Over-abstraction**: helpers/utilities created for one-time use,
55
+ premature abstractions, unnecessary indirection layers
56
+ 2. **Unnecessary complexity**: complex conditionals that could be simplified,
57
+ nested ternaries, over-engineered error handling for impossible cases
58
+ 3. **Dead paths**: code paths that can never execute given the current logic,
59
+ unused parameters, redundant null checks
60
+ 4. **Verbosity**: code that does in 10 lines what could be done in 3,
61
+ unnecessary intermediate variables, redundant type annotations
62
+ 5. **Missed language idioms**: patterns where the language has a simpler
63
+ built-in way (e.g., optional chaining, destructuring, list comprehensions)
64
+
65
+ For each finding, provide:
66
+ - File and line range
67
+ - Category (1-5 above)
68
+ - Current code (exact snippet)
69
+ - Simplified code (exact replacement)
70
+ - Why it's simpler (one sentence)
71
+
72
+ If the code is already clean, say "No simplifications found."
73
+ Do NOT suggest changes that alter behavior or add features.
74
+ ```
75
+
76
+ ## Phase 3 — Present Findings
77
+
78
+ Structure output by impact:
79
+
80
+ ```
81
+ ━━━ SIMPLIFY — {n} opportunities ━━━
82
+
83
+ {file}:{lines} — {category}
84
+ Before: {current code snippet}
85
+ After: {simplified code snippet}
86
+ Why: {one sentence}
87
+
88
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
89
+ ```
90
+
91
+ Ask: "Apply all / select specific / skip?"
92
+
93
+ ## Phase 4 — Apply Changes
94
+
95
+ For each approved simplification:
96
+ 1. Apply the edit
97
+ 2. Run the test suite after ALL edits
98
+ 3. If tests fail: revert the last edit, report which simplification broke tests
99
+ 4. Show final diff of simplifications applied
100
+
101
+ ## Phase 5 — Write Learning (optional)
102
+
103
+ If a pattern recurred (same category hit 3+ times):
104
+ - Write a `[LEARN:simplify]` entry to `{vault_path}/notes/learnings.md`:
105
+ ```markdown
106
+ ## [LEARN:simplify] {Pattern name}
107
+ - **What**: {what complexity pattern was found}
108
+ - **So What**: {why it makes code harder to maintain}
109
+ - **Now What**: {what to do instead going forward}
110
+ - **Date**: {YYYY-MM-DD}
111
+ ```
112
+
113
+ ## Error Handling
114
+
115
+ | Condition | Action |
116
+ |-----------|--------|
117
+ | Empty diff | Exit cleanly |
118
+ | Tests fail after simplification | Revert last edit, report |
119
+ | Subagent finds nothing | "Code is clean. No simplifications." |
120
+ | No test command configured | Warn, ask user to verify manually |
121
+
122
+ ## Integration Points
123
+
124
+ | Caller | When |
125
+ |--------|------|
126
+ | `/gsd:verify` Step 3b | After UNIFY, before session-retro |
127
+ | Manual `/simplify` | Any time after implementation |
128
+ | Ralph iteration | After story completion, before commit |
129
+
130
+ ## Removal Condition
131
+ Remove when an external linter or formatter handles all 5 simplification
132
+ categories with auto-fix support.
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: prd-writer
3
+ disable-model-invocation: true
4
+ description: Structured PRD authoring for Ralph. Gathers context, builds stories,
5
+ validates against Ralph constraints, writes PRD to vault. Invoke manually with
6
+ /prd-writer only. Side-effect skill — never auto-triggers.
7
+ allowed-tools: Bash, Read, Write, Edit
8
+ ---
9
+
10
+ # prd-writer Skill
11
+
12
+ ## Vault Path Resolution
13
+ Read vault_path from `~/.claude/praxis.config.json`. If missing: tell user to run `install.sh`.
14
+
15
+ ## DONE-WHEN
16
+ - [ ] PRD written to vault with all stories populated
17
+ - [ ] Every story has: role, capability, outcome, done-when, file group, dependencies, estimate
18
+ - [ ] No story marked L (must be split before writing)
19
+ - [ ] Total stories ≤15
20
+ - [ ] ralph_state.prd_path set in claude-progress.json
21
+ - [ ] status.md updated with PRD reference
22
+ - [ ] Vault indexed (automatic)
23
+
24
+ ## NON-GOALS
25
+ - Does not execute stories — that is Ralph's job
26
+ - Does not create plans — use `/plan` for that
27
+ - Does not write specs or ADRs — use `/spec` for that
28
+
29
+ ---
30
+
31
+ ## Phase 1 — Gather Context
32
+
33
+ 1. Read `{vault_path}/status.md` — current state and active work
34
+ 2. Read `{vault_path}/_index.md` — project goals and metadata
35
+ 3. Ask the user:
36
+ - What is the PRD objective? (one sentence)
37
+ - What area of the codebase does this cover?
38
+ - Any known constraints or dependencies?
39
+
40
+ ## Phase 2 — Build Stories
41
+
42
+ For each story, collect:
43
+ - **Title**: short identifier (e.g., `add-auth-middleware`)
44
+ - **As a**: role
45
+ - **I want**: capability
46
+ - **So that**: outcome
47
+ - **Done when**: list of verifiable checks
48
+ - **File group**: list of files (max 3 groups per story)
49
+ - **Dependencies**: story-ids that must complete first, or "none"
50
+ - **Estimate**: S / M / L
51
+
52
+ Present stories in a table for user review before proceeding.
53
+
54
+ ## Phase 3 — Validate Against Ralph Constraints
55
+
56
+ For each story, check:
57
+ - Completable in ~10k output tokens
58
+ - Touches ≤3 file groups
59
+ - Requires ≤1 architectural decision
60
+ - No cross-story reasoning required
61
+ - Estimate is S or M (never L)
62
+
63
+ Violations:
64
+ - L estimate → STOP. Story must be split before PRD is written.
65
+ - >3 file groups → STOP. Reduce scope or split.
66
+ - Cross-story dependency chains → WARN. Ralph executes stories independently.
67
+ - >15 stories total → suggest splitting into multiple PRDs.
68
+
69
+ ## Phase 4 — Write PRD
70
+
71
+ Use `references/prd-template.md` as the canonical format.
72
+
73
+ 1. Fill all fields. No placeholders may remain.
74
+ 2. Scan the output for unreplaced `{placeholder}` patterns. Zero must survive.
75
+ 3. Write to: `{vault_path}/plans/{YYYY-MM-DD}_{kebab-title}-prd.md`
76
+
77
+ ## Phase 5 — Wire State
78
+
79
+ 1. Update `{vault_path}/status.md`:
80
+ - Set `current_plan:` to the PRD path
81
+ - Update `## Now What` with "PRD ready for Ralph execution"
82
+ 2. Update `{vault_path}/claude-progress.json`:
83
+ - Set `ralph_state.prd_path` to the PRD file path
84
+ - Set `ralph_state.mode` to "idle"
85
+ - Set `ralph_state.completed_stories` to `[]`
86
+ - Set `ralph_state.blocked_stories` to `[]`
87
+ 3. Report:
88
+ ```
89
+ ✓ PRD written: {path}
90
+ ✓ Stories: {n} (S: {n}, M: {n})
91
+ ✓ ralph_state: prd_path set, mode idle
92
+ ✓ status.md: updated
93
+
94
+ Next: run /ralph to begin autonomous execution.
95
+ ```
96
+
97
+ ## Error Handling
98
+
99
+ | Condition | Action |
100
+ |-----------|--------|
101
+ | All stories marked L | Warn: "No stories are Ralph-suitable. Split or use GSD." |
102
+ | >15 stories | Suggest splitting into 2+ PRDs |
103
+ | Missing file groups | STOP. Every story needs a file group for Ralph |
104
+ | User declines story edits | Write PRD as-is with warnings noted |
105
+ | vault_path missing | Tell user to run install.sh |
106
+
107
+ ## Removal Condition
108
+ Remove when PRD authoring is fully automated from issue trackers or when Ralph accepts unstructured input.
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: {PRD title}
3
+ date: YYYY-MM-DD
4
+ status: active
5
+ stories_total: {n}
6
+ ---
7
+ # PRD: {title}
8
+
9
+ ## Context
10
+ Why this work exists. 1-3 sentences.
11
+
12
+ ## Stories
13
+
14
+ ### Story: {story-id}
15
+ **As a**: {role}
16
+ **I want**: {capability}
17
+ **So that**: {outcome}
18
+ **Done when**:
19
+ - [ ] {verifiable check}
20
+ **File group**: {list of files, max 3 groups}
21
+ **Dependencies**: {story-ids that must complete first, or "none"}
22
+ **Estimate**: S / M / L
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: pre-commit-lint
3
+ disable-model-invocation: true
4
+ description: Generate a stack-aware pre-commit hook script for a repo. Use when setting
5
+ up a new repo, when asked to "install pre-commit checks", "add linting to commits",
6
+ or "wire pre-commit-lint". Also invoked by scaffold-new Phase 5.5.
7
+ NOT invoked at commit time — generates a shell script that runs at commit time.
8
+ allowed-tools: Bash, Read, Write, Edit
9
+ ---
10
+
11
+ # pre-commit-lint Skill
12
+
13
+ ## WHAT
14
+ A `.git/hooks/pre-commit` bash script that:
15
+ 1. Always runs: secret scan + git identity check
16
+ 2. Conditionally runs: stack-specific linters based on staged file extensions
17
+ 3. Hard blocks on secrets, identity mismatch, and critical lint failures
18
+ 4. Warns (exit 0) on missing optional tools
19
+
20
+ ## DONE-WHEN
21
+ - [ ] `.git/hooks/pre-commit` exists and is executable
22
+ - [ ] `bash -n .git/hooks/pre-commit` passes
23
+ - [ ] Identity email hardcoded from repo CLAUDE.md
24
+ - [ ] Script detects staged file types before running stack checks
25
+ - [ ] All tool invocations guarded with `command -v <tool>`
26
+
27
+ ## CONSTRAINTS
28
+ - Script must complete in <10 seconds
29
+ - NEVER invoke `claude` inside the hook
30
+ - Tool not found → WARN and skip, never block
31
+ - Only block on: secrets, identity mismatch, syntax errors
32
+ - Portable bash (no zsh-isms)
33
+
34
+ ---
35
+
36
+ ## Phase 0 — Detect Stack and Identity
37
+
38
+ 1. Read `{repo_root}/CLAUDE.md` → extract `{identity_email}` and `{stack}`
39
+ 2. Detect stack from repo: `git ls-files | grep -E "\.(tf|ps1|yml|py|ts|sh|go)$" | sed 's/.*\.//' | sort -u`
40
+ 3. Check tool availability: tflint, tfsec, actionlint, ruff, mypy, terraform, shellcheck
41
+
42
+ ## Phase 1 — Generate Hook
43
+
44
+ Always include: preamble (helpers, staged file detection), identity check, secret scan.
45
+ Append stack sections based on detected flags:
46
+ - **Terraform**: fmt check, validate, layer boundary enforcement, tflint
47
+ - **PowerShell**: StrictMode check, ErrorActionPreference check, PSScriptAnalyzer
48
+ - **Shell**: bash -n syntax, set -euo check, shellcheck
49
+ - **GitHub Actions**: actionlint, unpinned action check
50
+ - **Python**: ruff, mypy
51
+ Append summary footer.
52
+
53
+ ## Phase 2 — Write and Verify
54
+
55
+ 1. Scan for unreplaced `{placeholder}` patterns — resolve all
56
+ 2. Write to `{repo_root}/.git/hooks/pre-commit`
57
+ 3. `chmod +x`
58
+ 4. `bash -n` syntax validation
59
+ 5. Report: checks enabled, tools missing
60
+
61
+ ## Error Handling
62
+
63
+ | Condition | Action |
64
+ |-----------|--------|
65
+ | CLAUDE.md missing Identity | Ask user for email |
66
+ | `bash -n` fails | Fix before writing |
67
+ | `.git/` not found | STOP — not a git repo |
68
+ | All tools missing for stack | Warn, generate with skip guards |
69
+
70
+ ## Removal Condition
71
+ Remove when hooks managed globally via dotfiles bootstrap.
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: scaffold-exist
3
+ disable-model-invocation: true
4
+ description: Scaffold an existing project into the full harness. Invoke with /scaffold-exist only.
5
+ Adds missing harness files to projects that predate the scaffold standard.
6
+ Non-destructive — never overwrites without confirmation. Side-effect skill — never auto-triggers.
7
+ ---
8
+
9
+ # scaffold-exist Skill
10
+
11
+ ## Vault Path Resolution
12
+ Read vault_path from `~/.claude/praxis.config.json`. If missing: STOP.
13
+
14
+ ## WHAT
15
+ Bring an existing project into full harness compliance without disrupting active work.
16
+
17
+ ## DONE-WHEN
18
+ - [ ] `{vault_path}/status.md` exists with correct structure
19
+ - [ ] `{vault_path}/tasks.md` exists
20
+ - [ ] `{vault_path}/claude-progress.json` exists
21
+ - [ ] `{vault_path}/specs/` and `research/` directories exist
22
+ - [ ] `{vault_path}/_index.md` has `local_path` matching actual repo path
23
+ - [ ] Repo `CLAUDE.md` has `## Vault Project` section
24
+ - [ ] Repo `CLAUDE.md` has bootstrap sequence
25
+ - [ ] Project Registry row is accurate
26
+
27
+ ## CONSTRAINTS
28
+ - NEVER delete existing vault content — only add missing files
29
+ - NEVER overwrite without explicit user confirmation
30
+ - Read `_index.md` to resolve metadata — do not ask for info already there
31
+
32
+ ## NON-GOALS
33
+ - Does not reformat existing vault notes
34
+ - Does not touch existing specs/, research/, notes/ content
35
+ - Does not change git history or branch structure
36
+
37
+ ---
38
+
39
+ ## Phase 0 — Audit
40
+
41
+ Ask user: which project? (slug or vault path)
42
+ Compute vault_path from config. Run: `ls -la {vault_path}/`
43
+
44
+ Build and show audit table:
45
+
46
+ | File/Dir | Exists? | Action |
47
+ |----------|---------|--------|
48
+ | `_index.md` | ? | Verify `local_path` field |
49
+ | `status.md` | ? | Create if missing |
50
+ | `tasks.md` | ? | Create if missing |
51
+ | `claude-progress.json` | ? | Create if missing |
52
+ | `plans/` | ? | Create if missing |
53
+ | `specs/` | ? | Create if missing |
54
+ | `research/` | ? | Create if missing |
55
+ | `notes/learnings.md` | ? | Create if missing |
56
+ | Repo CLAUDE.md sections | ? | Add missing sections |
57
+ | Registry row | ? | Verify accuracy |
58
+
59
+ **Get user confirmation before Phase 1.**
60
+
61
+ ## Phase 1 — Resolve Metadata
62
+ Read `_index.md`, extract project name, slug, repo_root, type, stack, repo_url.
63
+ Verify repo_root exists on disk.
64
+
65
+ ## Phase 2 — Create Missing Vault Files
66
+ Use same templates as scaffold-new (`references/` dir). Existing files untouched.
67
+ Vault indexing is automatic.
68
+
69
+ ## Phase 3 — Update Repo CLAUDE.md
70
+ If missing: create from template. If exists: add only missing sections (Vault Project, bootstrap, Identity). Preserve existing content.
71
+
72
+ ## Phase 4 — Verify Project Registry
73
+ Read vault CLAUDE.md registry. Row missing → append. Row inaccurate → update.
74
+
75
+ ## Error Handling
76
+
77
+ | Condition | Action |
78
+ |-----------|--------|
79
+ | `_index.md` missing | STOP — run scaffold-new instead |
80
+ | `local_path` doesn't exist | Warn, ask for correct path |
81
+ | Existing file would be overwritten | Ask explicit confirmation |
82
+ | Vault search fails | Warn only |
83
+
84
+ ## Removal Condition
85
+ Remove when all active projects are migrated and scaffold-new is the only entry path.