anvil-dev-framework 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +719 -0
- package/VERSION +1 -0
- package/docs/ANVIL-REPO-IMPLEMENTATION-PLAN.md +441 -0
- package/docs/FIRST-SKILL-TUTORIAL.md +408 -0
- package/docs/INSTALLATION-RETRO-NOTES.md +458 -0
- package/docs/INSTALLATION.md +984 -0
- package/docs/anvil-hud.md +469 -0
- package/docs/anvil-init.md +255 -0
- package/docs/anvil-state.md +210 -0
- package/docs/boris-cherny-ralph-wiggum-insights.md +608 -0
- package/docs/command-reference.md +2022 -0
- package/docs/hooks-tts.md +368 -0
- package/docs/implementation-guide.md +810 -0
- package/docs/linear-github-integration.md +247 -0
- package/docs/local-issues.md +677 -0
- package/docs/patterns/README.md +419 -0
- package/docs/planning-responsibilities.md +139 -0
- package/docs/session-workflow.md +573 -0
- package/docs/simplification-plan-template.md +297 -0
- package/docs/simplification-principles.md +129 -0
- package/docs/specifications/CCS-RALPH-INTEGRATION-DESIGN.md +633 -0
- package/docs/specifications/CCS-RESEARCH-REPORT.md +169 -0
- package/docs/specifications/PLAN-ANV-verification-ralph-wiggum.md +403 -0
- package/docs/specifications/PLAN-parallel-tracks-anvil-memory-ccs.md +494 -0
- package/docs/specifications/SPEC-ANV-VRW/component-01-verify.md +208 -0
- package/docs/specifications/SPEC-ANV-VRW/component-02-stop-gate.md +226 -0
- package/docs/specifications/SPEC-ANV-VRW/component-03-posttooluse.md +209 -0
- package/docs/specifications/SPEC-ANV-VRW/component-04-ralph-wiggum.md +604 -0
- package/docs/specifications/SPEC-ANV-VRW/component-05-atomic-actions.md +311 -0
- package/docs/specifications/SPEC-ANV-VRW/component-06-verify-subagent.md +264 -0
- package/docs/specifications/SPEC-ANV-VRW/component-07-claude-md.md +363 -0
- package/docs/specifications/SPEC-ANV-VRW/index.md +182 -0
- package/docs/specifications/SPEC-ANV-anvil-memory.md +573 -0
- package/docs/specifications/SPEC-ANV-context-checkpoints.md +781 -0
- package/docs/specifications/SPEC-ANV-verification-ralph-wiggum.md +789 -0
- package/docs/sync.md +122 -0
- package/global/CLAUDE.md +140 -0
- package/global/agents/verify-app.md +164 -0
- package/global/commands/anvil-settings.md +527 -0
- package/global/commands/anvil-sync.md +121 -0
- package/global/commands/change.md +197 -0
- package/global/commands/clarify.md +252 -0
- package/global/commands/cleanup.md +292 -0
- package/global/commands/commit-push-pr.md +207 -0
- package/global/commands/decay-review.md +127 -0
- package/global/commands/discover.md +158 -0
- package/global/commands/doc-coverage.md +122 -0
- package/global/commands/evidence.md +307 -0
- package/global/commands/explore.md +121 -0
- package/global/commands/force-exit.md +135 -0
- package/global/commands/handoff.md +191 -0
- package/global/commands/healthcheck.md +302 -0
- package/global/commands/hud.md +84 -0
- package/global/commands/insights.md +319 -0
- package/global/commands/linear-setup.md +184 -0
- package/global/commands/lint-fix.md +198 -0
- package/global/commands/orient.md +510 -0
- package/global/commands/plan.md +228 -0
- package/global/commands/ralph.md +346 -0
- package/global/commands/ready.md +182 -0
- package/global/commands/release.md +305 -0
- package/global/commands/retro.md +96 -0
- package/global/commands/shard.md +166 -0
- package/global/commands/spec.md +227 -0
- package/global/commands/sprint.md +184 -0
- package/global/commands/tasks.md +228 -0
- package/global/commands/test-and-commit.md +151 -0
- package/global/commands/validate.md +132 -0
- package/global/commands/verify.md +251 -0
- package/global/commands/weekly-review.md +156 -0
- package/global/hooks/__pycache__/ralph_context_monitor.cpython-314.pyc +0 -0
- package/global/hooks/__pycache__/statusline_agent_sync.cpython-314.pyc +0 -0
- package/global/hooks/anvil_memory_observe.ts +322 -0
- package/global/hooks/anvil_memory_session.ts +166 -0
- package/global/hooks/anvil_memory_stop.ts +187 -0
- package/global/hooks/parse_transcript.py +116 -0
- package/global/hooks/post_merge_cleanup.sh +132 -0
- package/global/hooks/post_tool_format.sh +215 -0
- package/global/hooks/ralph_context_monitor.py +240 -0
- package/global/hooks/ralph_stop.sh +502 -0
- package/global/hooks/statusline.sh +1110 -0
- package/global/hooks/statusline_agent_sync.py +224 -0
- package/global/hooks/stop_gate.sh +250 -0
- package/global/lib/.claude/anvil-state.json +21 -0
- package/global/lib/__pycache__/agent_registry.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/claim_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coderabbit_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/config_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coordination_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/doc_coverage_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/gate_logger.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/github_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/hygiene_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_data_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/local_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/quality_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/transcript_parser.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verification_runner.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_iteration.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_subagent.cpython-314.pyc +0 -0
- package/global/lib/agent_registry.py +995 -0
- package/global/lib/anvil-state.sh +435 -0
- package/global/lib/claim_service.py +515 -0
- package/global/lib/coderabbit_service.py +314 -0
- package/global/lib/config_service.py +423 -0
- package/global/lib/coordination_service.py +331 -0
- package/global/lib/doc_coverage_service.py +1305 -0
- package/global/lib/gate_logger.py +316 -0
- package/global/lib/github_service.py +310 -0
- package/global/lib/handoff_generator.py +775 -0
- package/global/lib/hygiene_service.py +712 -0
- package/global/lib/issue_models.py +257 -0
- package/global/lib/issue_provider.py +339 -0
- package/global/lib/linear_data_service.py +210 -0
- package/global/lib/linear_provider.py +987 -0
- package/global/lib/linear_provider.py.backup +671 -0
- package/global/lib/local_provider.py +486 -0
- package/global/lib/orient_fast.py +457 -0
- package/global/lib/quality_service.py +470 -0
- package/global/lib/ralph_prompt_generator.py +563 -0
- package/global/lib/ralph_state.py +1202 -0
- package/global/lib/state_manager.py +417 -0
- package/global/lib/transcript_parser.py +597 -0
- package/global/lib/verification_runner.py +557 -0
- package/global/lib/verify_iteration.py +490 -0
- package/global/lib/verify_subagent.py +250 -0
- package/global/skills/README.md +155 -0
- package/global/skills/quality-gates/SKILL.md +252 -0
- package/global/skills/skill-template/SKILL.md +109 -0
- package/global/skills/testing-strategies/SKILL.md +337 -0
- package/global/templates/CHANGE-template.md +105 -0
- package/global/templates/HANDOFF-template.md +63 -0
- package/global/templates/PLAN-template.md +111 -0
- package/global/templates/SPEC-template.md +93 -0
- package/global/templates/ralph/PROMPT.md.template +89 -0
- package/global/templates/ralph/fix_plan.md.template +31 -0
- package/global/templates/ralph/progress.txt.template +23 -0
- package/global/tests/__pycache__/test_doc_coverage.cpython-314.pyc +0 -0
- package/global/tests/test_doc_coverage.py +520 -0
- package/global/tests/test_issue_models.py +299 -0
- package/global/tests/test_local_provider.py +323 -0
- package/global/tools/README.md +178 -0
- package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
- package/global/tools/anvil-hud.py +3622 -0
- package/global/tools/anvil-hud.py.bak +3318 -0
- package/global/tools/anvil-issue.py +432 -0
- package/global/tools/anvil-memory/CLAUDE.md +49 -0
- package/global/tools/anvil-memory/README.md +42 -0
- package/global/tools/anvil-memory/bun.lock +25 -0
- package/global/tools/anvil-memory/bunfig.toml +9 -0
- package/global/tools/anvil-memory/package.json +23 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +535 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/edge-cases.test.ts +645 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +363 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +8 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/integration.test.ts +417 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +571 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +440 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +252 -0
- package/global/tools/anvil-memory/src/__tests__/commands.test.ts +657 -0
- package/global/tools/anvil-memory/src/__tests__/db.test.ts +641 -0
- package/global/tools/anvil-memory/src/__tests__/hooks.test.ts +272 -0
- package/global/tools/anvil-memory/src/__tests__/performance.test.ts +427 -0
- package/global/tools/anvil-memory/src/__tests__/test-utils.ts +113 -0
- package/global/tools/anvil-memory/src/commands/checkpoint.ts +197 -0
- package/global/tools/anvil-memory/src/commands/get.ts +115 -0
- package/global/tools/anvil-memory/src/commands/init.ts +94 -0
- package/global/tools/anvil-memory/src/commands/observe.ts +163 -0
- package/global/tools/anvil-memory/src/commands/search.ts +112 -0
- package/global/tools/anvil-memory/src/db.ts +638 -0
- package/global/tools/anvil-memory/src/index.ts +205 -0
- package/global/tools/anvil-memory/src/types.ts +122 -0
- package/global/tools/anvil-memory/tsconfig.json +29 -0
- package/global/tools/ralph-loop.sh +359 -0
- package/package.json +45 -0
- package/scripts/anvil +822 -0
- package/scripts/extract_patterns.py +222 -0
- package/scripts/init-project.sh +541 -0
- package/scripts/install.sh +229 -0
- package/scripts/postinstall.js +41 -0
- package/scripts/rollback.sh +188 -0
- package/scripts/sync.sh +623 -0
- package/scripts/test-statusline.sh +248 -0
- package/scripts/update_claude_md.py +224 -0
- package/scripts/verify.sh +255 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
---
|
|
2
|
+
shard_id: SPEC-ANV-VRW/component-07
|
|
3
|
+
parent: SPEC-ANV-VRW
|
|
4
|
+
title: Automated CLAUDE.md Updates
|
|
5
|
+
status: draft
|
|
6
|
+
linear_issue: ANV-147
|
|
7
|
+
priority: P2
|
|
8
|
+
estimated_hours: 3-4
|
|
9
|
+
dependencies:
|
|
10
|
+
- component-01-verify
|
|
11
|
+
- component-05-atomic-actions
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Component 7: Automated CLAUDE.md Updates
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
GitHub Action that extracts patterns from commits and updates CLAUDE.md automatically. This keeps project context fresh without manual maintenance.
|
|
19
|
+
|
|
20
|
+
> Boris Cherny: "GitHub Actions extraction for CLAUDE.md"
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
| ID | Requirement | Priority | Acceptance Criteria |
|
|
27
|
+
|----|-------------|----------|---------------------|
|
|
28
|
+
| REQ-AC-100 | Weekly GitHub Action runs pattern extraction | P1 | Action runs on schedule |
|
|
29
|
+
| REQ-AC-101 | Extracts common patterns from commit messages | P1 | Patterns identified |
|
|
30
|
+
| REQ-AC-102 | Updates CLAUDE.md Project-Learned Patterns section | P1 | Table updated correctly |
|
|
31
|
+
| REQ-AC-103 | Creates PR for human review (no auto-merge) | P0 | PR created, not merged |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Implementation Tasks
|
|
36
|
+
|
|
37
|
+
### Task 1: Create Pattern Extraction Script
|
|
38
|
+
**File**: `scripts/extract_patterns.py`
|
|
39
|
+
**Estimated**: 1.5 hours
|
|
40
|
+
|
|
41
|
+
- [ ] Parse commit messages from last week
|
|
42
|
+
- [ ] Identify recurring patterns (prefixes, file types, etc.)
|
|
43
|
+
- [ ] Extract issue references (ANV-XX, etc.)
|
|
44
|
+
- [ ] Categorize by type (fix, feat, refactor)
|
|
45
|
+
- [ ] Output structured JSON
|
|
46
|
+
|
|
47
|
+
### Task 2: Create CLAUDE.md Updater
|
|
48
|
+
**File**: `scripts/update_claude_md.py`
|
|
49
|
+
**Estimated**: 1 hour
|
|
50
|
+
|
|
51
|
+
- [ ] Read current CLAUDE.md
|
|
52
|
+
- [ ] Parse Project-Learned Patterns table
|
|
53
|
+
- [ ] Merge new patterns (avoid duplicates)
|
|
54
|
+
- [ ] Update table with dates
|
|
55
|
+
- [ ] Write updated file
|
|
56
|
+
|
|
57
|
+
### Task 3: Create GitHub Action
|
|
58
|
+
**File**: `.github/workflows/update-claude-md.yml`
|
|
59
|
+
**Estimated**: 1 hour
|
|
60
|
+
|
|
61
|
+
- [ ] Weekly schedule (Sundays)
|
|
62
|
+
- [ ] Manual trigger option
|
|
63
|
+
- [ ] Run extraction script
|
|
64
|
+
- [ ] Run update script
|
|
65
|
+
- [ ] Create PR with changes
|
|
66
|
+
|
|
67
|
+
### Task 4: Testing and Validation
|
|
68
|
+
**Estimated**: 0.5 hours
|
|
69
|
+
|
|
70
|
+
- [ ] Test with sample commit history
|
|
71
|
+
- [ ] Verify PR creation
|
|
72
|
+
- [ ] Ensure no auto-merge
|
|
73
|
+
- [ ] Test manual trigger
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## GitHub Action
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
# .github/workflows/update-claude-md.yml
|
|
81
|
+
name: Update CLAUDE.md
|
|
82
|
+
|
|
83
|
+
on:
|
|
84
|
+
schedule:
|
|
85
|
+
- cron: '0 0 * * 0' # Weekly on Sunday midnight
|
|
86
|
+
workflow_dispatch: # Allow manual trigger
|
|
87
|
+
|
|
88
|
+
jobs:
|
|
89
|
+
extract-patterns:
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
permissions:
|
|
92
|
+
contents: write
|
|
93
|
+
pull-requests: write
|
|
94
|
+
|
|
95
|
+
steps:
|
|
96
|
+
- name: Checkout repository
|
|
97
|
+
uses: actions/checkout@v4
|
|
98
|
+
with:
|
|
99
|
+
fetch-depth: 0 # Full history for commit analysis
|
|
100
|
+
|
|
101
|
+
- name: Set up Python
|
|
102
|
+
uses: actions/setup-python@v5
|
|
103
|
+
with:
|
|
104
|
+
python-version: '3.11'
|
|
105
|
+
|
|
106
|
+
- name: Install dependencies
|
|
107
|
+
run: pip install pyyaml
|
|
108
|
+
|
|
109
|
+
- name: Extract patterns from recent commits
|
|
110
|
+
run: |
|
|
111
|
+
python scripts/extract_patterns.py > patterns.json
|
|
112
|
+
|
|
113
|
+
- name: Update CLAUDE.md
|
|
114
|
+
run: |
|
|
115
|
+
python scripts/update_claude_md.py patterns.json
|
|
116
|
+
|
|
117
|
+
- name: Check for changes
|
|
118
|
+
id: changes
|
|
119
|
+
run: |
|
|
120
|
+
if git diff --quiet CLAUDE.md; then
|
|
121
|
+
echo "changed=false" >> $GITHUB_OUTPUT
|
|
122
|
+
else
|
|
123
|
+
echo "changed=true" >> $GITHUB_OUTPUT
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
- name: Create Pull Request
|
|
127
|
+
if: steps.changes.outputs.changed == 'true'
|
|
128
|
+
uses: peter-evans/create-pull-request@v5
|
|
129
|
+
with:
|
|
130
|
+
title: "chore: update CLAUDE.md patterns [automated]"
|
|
131
|
+
body: |
|
|
132
|
+
## Automated Pattern Extraction
|
|
133
|
+
|
|
134
|
+
This PR updates the Project-Learned Patterns section in CLAUDE.md
|
|
135
|
+
based on analysis of recent commits.
|
|
136
|
+
|
|
137
|
+
**Review carefully before merging.**
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
*Generated by weekly CLAUDE.md update workflow*
|
|
141
|
+
branch: auto/claude-md-update
|
|
142
|
+
labels: automated,documentation
|
|
143
|
+
commit-message: "chore: update CLAUDE.md patterns"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Pattern Extraction Script
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
#!/usr/bin/env python3
|
|
152
|
+
"""
|
|
153
|
+
Extract patterns from recent git commits.
|
|
154
|
+
|
|
155
|
+
Usage: python scripts/extract_patterns.py > patterns.json
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
import subprocess
|
|
159
|
+
import json
|
|
160
|
+
import re
|
|
161
|
+
from collections import Counter
|
|
162
|
+
from datetime import datetime, timedelta
|
|
163
|
+
|
|
164
|
+
def get_recent_commits(days=7):
|
|
165
|
+
"""Get commits from the last N days."""
|
|
166
|
+
since = (datetime.now() - timedelta(days=days)).isoformat()
|
|
167
|
+
result = subprocess.run(
|
|
168
|
+
['git', 'log', f'--since={since}', '--pretty=format:%s||%h||%an'],
|
|
169
|
+
capture_output=True, text=True
|
|
170
|
+
)
|
|
171
|
+
commits = []
|
|
172
|
+
for line in result.stdout.strip().split('\n'):
|
|
173
|
+
if '||' in line:
|
|
174
|
+
parts = line.split('||')
|
|
175
|
+
commits.append({
|
|
176
|
+
'message': parts[0],
|
|
177
|
+
'hash': parts[1],
|
|
178
|
+
'author': parts[2]
|
|
179
|
+
})
|
|
180
|
+
return commits
|
|
181
|
+
|
|
182
|
+
def extract_patterns(commits):
|
|
183
|
+
"""Identify patterns in commit messages."""
|
|
184
|
+
patterns = []
|
|
185
|
+
|
|
186
|
+
# Count commit prefixes
|
|
187
|
+
prefix_counter = Counter()
|
|
188
|
+
issue_refs = Counter()
|
|
189
|
+
file_patterns = Counter()
|
|
190
|
+
|
|
191
|
+
for commit in commits:
|
|
192
|
+
msg = commit['message']
|
|
193
|
+
|
|
194
|
+
# Extract conventional commit prefix
|
|
195
|
+
prefix_match = re.match(r'^(\w+)[\(:]', msg)
|
|
196
|
+
if prefix_match:
|
|
197
|
+
prefix_counter[prefix_match.group(1)] += 1
|
|
198
|
+
|
|
199
|
+
# Extract issue references
|
|
200
|
+
issues = re.findall(r'[A-Z]+-\d+', msg)
|
|
201
|
+
for issue in issues:
|
|
202
|
+
issue_refs[issue] += 1
|
|
203
|
+
|
|
204
|
+
# Extract file/component mentions
|
|
205
|
+
components = re.findall(r'\(([^)]+)\)', msg)
|
|
206
|
+
for comp in components:
|
|
207
|
+
file_patterns[comp] += 1
|
|
208
|
+
|
|
209
|
+
# Convert to patterns
|
|
210
|
+
if prefix_counter:
|
|
211
|
+
top_prefix = prefix_counter.most_common(1)[0]
|
|
212
|
+
if top_prefix[1] >= 3:
|
|
213
|
+
patterns.append({
|
|
214
|
+
'name': f'{top_prefix[0].title()} Commits',
|
|
215
|
+
'description': f'Most common commit type ({top_prefix[1]} commits)',
|
|
216
|
+
'evidence': ', '.join(issue_refs.keys())[:50]
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
for comp, count in file_patterns.most_common(3):
|
|
220
|
+
if count >= 2:
|
|
221
|
+
patterns.append({
|
|
222
|
+
'name': f'{comp} Focus',
|
|
223
|
+
'description': f'Frequent changes to {comp} ({count} commits)',
|
|
224
|
+
'evidence': ', '.join(list(issue_refs.keys())[:3])
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
return patterns
|
|
228
|
+
|
|
229
|
+
def main():
|
|
230
|
+
commits = get_recent_commits()
|
|
231
|
+
patterns = extract_patterns(commits)
|
|
232
|
+
print(json.dumps({
|
|
233
|
+
'extracted_at': datetime.now().isoformat(),
|
|
234
|
+
'commit_count': len(commits),
|
|
235
|
+
'patterns': patterns
|
|
236
|
+
}, indent=2))
|
|
237
|
+
|
|
238
|
+
if __name__ == '__main__':
|
|
239
|
+
main()
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## CLAUDE.md Updater Script
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
#!/usr/bin/env python3
|
|
248
|
+
"""
|
|
249
|
+
Update CLAUDE.md with extracted patterns.
|
|
250
|
+
|
|
251
|
+
Usage: python scripts/update_claude_md.py patterns.json
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
import sys
|
|
255
|
+
import json
|
|
256
|
+
import re
|
|
257
|
+
from datetime import datetime
|
|
258
|
+
|
|
259
|
+
def read_file(path):
|
|
260
|
+
with open(path, 'r') as f:
|
|
261
|
+
return f.read()
|
|
262
|
+
|
|
263
|
+
def write_file(path, content):
|
|
264
|
+
with open(path, 'w') as f:
|
|
265
|
+
f.write(content)
|
|
266
|
+
|
|
267
|
+
def parse_patterns_table(content):
|
|
268
|
+
"""Extract existing patterns from CLAUDE.md."""
|
|
269
|
+
pattern = r'\| Pattern \| Evidence \| Added \|\n\|[-|]+\|\n((?:\|[^|]+\|[^|]+\|[^|]+\|\n)*)'
|
|
270
|
+
match = re.search(pattern, content)
|
|
271
|
+
if not match:
|
|
272
|
+
return []
|
|
273
|
+
|
|
274
|
+
rows = match.group(1).strip().split('\n')
|
|
275
|
+
patterns = []
|
|
276
|
+
for row in rows:
|
|
277
|
+
cols = [c.strip() for c in row.split('|')[1:-1]]
|
|
278
|
+
if len(cols) == 3:
|
|
279
|
+
patterns.append({
|
|
280
|
+
'name': cols[0],
|
|
281
|
+
'evidence': cols[1],
|
|
282
|
+
'added': cols[2]
|
|
283
|
+
})
|
|
284
|
+
return patterns
|
|
285
|
+
|
|
286
|
+
def merge_patterns(existing, new):
|
|
287
|
+
"""Merge new patterns with existing, avoiding duplicates."""
|
|
288
|
+
names = {p['name'] for p in existing}
|
|
289
|
+
today = datetime.now().strftime('%Y-%m-%d')
|
|
290
|
+
|
|
291
|
+
merged = list(existing)
|
|
292
|
+
for pattern in new:
|
|
293
|
+
if pattern['name'] not in names:
|
|
294
|
+
merged.append({
|
|
295
|
+
'name': pattern['name'],
|
|
296
|
+
'evidence': pattern.get('evidence', ''),
|
|
297
|
+
'added': today
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
return merged
|
|
301
|
+
|
|
302
|
+
def format_table(patterns):
|
|
303
|
+
"""Format patterns as markdown table."""
|
|
304
|
+
lines = ['| Pattern | Evidence | Added |', '|---------|----------|-------|']
|
|
305
|
+
for p in patterns:
|
|
306
|
+
lines.append(f"| {p['name']} | {p['evidence']} | {p['added']} |")
|
|
307
|
+
return '\n'.join(lines)
|
|
308
|
+
|
|
309
|
+
def update_claude_md(patterns_file):
|
|
310
|
+
with open(patterns_file) as f:
|
|
311
|
+
new_data = json.load(f)
|
|
312
|
+
|
|
313
|
+
content = read_file('CLAUDE.md')
|
|
314
|
+
existing = parse_patterns_table(content)
|
|
315
|
+
merged = merge_patterns(existing, new_data.get('patterns', []))
|
|
316
|
+
|
|
317
|
+
new_table = format_table(merged)
|
|
318
|
+
|
|
319
|
+
# Replace the table in CLAUDE.md
|
|
320
|
+
pattern = r'(\| Pattern \| Evidence \| Added \|\n\|[-|]+\|\n)((?:\|[^|]+\|[^|]+\|[^|]+\|\n)*)'
|
|
321
|
+
updated = re.sub(pattern, new_table + '\n', content)
|
|
322
|
+
|
|
323
|
+
write_file('CLAUDE.md', updated)
|
|
324
|
+
print(f"Updated CLAUDE.md with {len(merged)} patterns")
|
|
325
|
+
|
|
326
|
+
if __name__ == '__main__':
|
|
327
|
+
if len(sys.argv) != 2:
|
|
328
|
+
print("Usage: python update_claude_md.py patterns.json")
|
|
329
|
+
sys.exit(1)
|
|
330
|
+
update_claude_md(sys.argv[1])
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Test Cases
|
|
336
|
+
|
|
337
|
+
| Test Case | Input | Expected |
|
|
338
|
+
|-----------|-------|----------|
|
|
339
|
+
| Fresh run | No existing patterns | New patterns added |
|
|
340
|
+
| Duplicate patterns | Same pattern name | Not duplicated |
|
|
341
|
+
| No new patterns | Quiet week | No PR created |
|
|
342
|
+
| Manual trigger | workflow_dispatch | Action runs on demand |
|
|
343
|
+
| PR created | Changes detected | PR with `automated` label |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Safety Measures
|
|
348
|
+
|
|
349
|
+
| Concern | Mitigation |
|
|
350
|
+
|---------|------------|
|
|
351
|
+
| Bad patterns | Human review via PR |
|
|
352
|
+
| Overwriting good content | Merge, don't replace |
|
|
353
|
+
| Spam PRs | Only create if changes exist |
|
|
354
|
+
| Auto-merge risk | No auto-merge, require approval |
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Integration Points
|
|
359
|
+
|
|
360
|
+
- **Trigger**: Weekly schedule or manual
|
|
361
|
+
- **Input**: Git commit history
|
|
362
|
+
- **Output**: Updated CLAUDE.md via PR
|
|
363
|
+
- **Dependencies**: None (standalone workflow)
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_id: SPEC-ANV-VRW
|
|
3
|
+
title: Verification Feedback Loops & Ralph Wiggum Mode
|
|
4
|
+
status: draft
|
|
5
|
+
created: 2026-01-04
|
|
6
|
+
updated: 2026-01-04
|
|
7
|
+
linear_issue: ANV-140
|
|
8
|
+
sharded: true
|
|
9
|
+
references:
|
|
10
|
+
- https://x.com/bcherny/status/2007179832300581177
|
|
11
|
+
- https://github.com/anthropics/claude-code/tree/main/plugins/ralph-wiggum
|
|
12
|
+
- docs/boris-cherny-ralph-wiggum-insights.md
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Verification Feedback Loops & Ralph Wiggum Mode
|
|
16
|
+
|
|
17
|
+
## Executive Summary
|
|
18
|
+
|
|
19
|
+
This specification implements proven methodologies from Boris Cherny (Claude Code creator) and Geoffrey Huntley's Ralph Wiggum technique to achieve **2-3x quality improvements** through verification feedback loops and enable **long-running unattended execution**.
|
|
20
|
+
|
|
21
|
+
### Key Outcomes
|
|
22
|
+
- **Verification-first workflow** that catches issues before they compound
|
|
23
|
+
- **Stop hook gates** that prevent premature task completion
|
|
24
|
+
- **Ralph Wiggum mode** for overnight/unattended execution
|
|
25
|
+
- **Atomic action commands** for rapid inner-loop execution
|
|
26
|
+
- **Self-improving CLAUDE.md** via automated pattern extraction
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Shards
|
|
31
|
+
|
|
32
|
+
| Shard | Title | Linear | Status | Priority |
|
|
33
|
+
|-------|-------|--------|--------|----------|
|
|
34
|
+
| [component-01-verify](./component-01-verify.md) | `/verify` Command | ANV-141 | Draft | P0 |
|
|
35
|
+
| [component-02-stop-gate](./component-02-stop-gate.md) | Stop Hook Verification Gate | ANV-142 | Draft | P0 |
|
|
36
|
+
| [component-03-posttooluse](./component-03-posttooluse.md) | PostToolUse Formatting Hook | ANV-143 | Draft | P0 |
|
|
37
|
+
| [component-04-ralph-wiggum](./component-04-ralph-wiggum.md) | Ralph Wiggum Mode | ANV-144/145 | Draft | P1 |
|
|
38
|
+
| [component-05-atomic-actions](./component-05-atomic-actions.md) | Atomic Action Commands | ANV-146 | Draft | P1 |
|
|
39
|
+
| [component-06-verify-subagent](./component-06-verify-subagent.md) | Verification Subagent | ANV-147 | Draft | P2 |
|
|
40
|
+
| [component-07-claude-md](./component-07-claude-md.md) | Automated CLAUDE.md Updates | ANV-147 | Draft | P2 |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Problem Statement
|
|
45
|
+
|
|
46
|
+
### Current Gaps vs. Best Practices
|
|
47
|
+
|
|
48
|
+
| Gap | Impact | Boris/Ralph Evidence |
|
|
49
|
+
|-----|--------|---------------------|
|
|
50
|
+
| No verification feedback loop | Errors compound, manual QA required | Boris: "2-3x quality improvement" |
|
|
51
|
+
| No stop hook gating | Claude exits with failing tests | Boris: Non-zero exit blocks stopping |
|
|
52
|
+
| No PostToolUse formatting | Manual formatting, inconsistent code | Boris: Auto-format on every edit |
|
|
53
|
+
| No long-running mode | Requires constant supervision | Geoffrey: 6 repos overnight, $50k→$297 |
|
|
54
|
+
| Scattered atomic actions | Slow inner loops | Boris: `/commit-push-pr` one-liners |
|
|
55
|
+
| Manual CLAUDE.md updates | Stale project context | Boris: GitHub Actions extraction |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Goals
|
|
60
|
+
|
|
61
|
+
| Goal | Success Metric |
|
|
62
|
+
|------|---------------|
|
|
63
|
+
| Verification-first workflow | All PRs pass CI before human review |
|
|
64
|
+
| Stop hook enforcement | Zero exits with failing tests |
|
|
65
|
+
| Unattended execution | 4+ hour autonomous sessions |
|
|
66
|
+
| Rapid inner loops | Single command for test→commit→push→PR |
|
|
67
|
+
| Self-improving context | CLAUDE.md updated weekly from commits |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Cross-Cutting Concerns
|
|
72
|
+
|
|
73
|
+
### Configuration Schema
|
|
74
|
+
|
|
75
|
+
All components share a common configuration in `.claude/settings.yaml`:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
verification:
|
|
79
|
+
enabled: true
|
|
80
|
+
commands:
|
|
81
|
+
test: "npm test"
|
|
82
|
+
lint: "npm run lint"
|
|
83
|
+
types: "npm run typecheck"
|
|
84
|
+
max_iterations: 3
|
|
85
|
+
required_for_completion: true
|
|
86
|
+
|
|
87
|
+
ralph_wiggum:
|
|
88
|
+
enabled: false
|
|
89
|
+
max_iterations: 50
|
|
90
|
+
commit_on_success: true
|
|
91
|
+
|
|
92
|
+
formatting:
|
|
93
|
+
enabled: true
|
|
94
|
+
timeout_ms: 500
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Shared Dependencies
|
|
98
|
+
|
|
99
|
+
- All hooks require bash
|
|
100
|
+
- PostToolUse requires formatters (prettier, black, etc.)
|
|
101
|
+
- Ralph Wiggum requires `/verify` component
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Dependencies Between Shards
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
component-01-verify ──┬──> component-02-stop-gate
|
|
109
|
+
│
|
|
110
|
+
├──> component-04-ralph-wiggum ──> component-05-atomic-actions
|
|
111
|
+
│
|
|
112
|
+
└──> component-06-verify-subagent
|
|
113
|
+
|
|
114
|
+
component-03-posttooluse (independent, can parallel)
|
|
115
|
+
|
|
116
|
+
component-07-claude-md (requires component-01, component-05)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## File Structure
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
global/
|
|
125
|
+
├── commands/
|
|
126
|
+
│ ├── verify.md # /verify skill
|
|
127
|
+
│ ├── ralph.md # /ralph skill
|
|
128
|
+
│ ├── test-and-commit.md # Atomic action
|
|
129
|
+
│ ├── commit-push-pr.md # Atomic action
|
|
130
|
+
│ ├── lint-fix.md # Atomic action
|
|
131
|
+
│ └── force-exit.md # Override command
|
|
132
|
+
├── hooks/
|
|
133
|
+
│ ├── stop_gate.sh # Verification stop hook
|
|
134
|
+
│ ├── ralph_stop.sh # Ralph Wiggum stop hook
|
|
135
|
+
│ └── post_tool_format.sh # PostToolUse formatter
|
|
136
|
+
├── lib/
|
|
137
|
+
│ ├── verification_runner.py
|
|
138
|
+
│ └── verify_iteration.py
|
|
139
|
+
└── agents/
|
|
140
|
+
└── verify-app.json # Verification subagent
|
|
141
|
+
|
|
142
|
+
.github/
|
|
143
|
+
└── workflows/
|
|
144
|
+
└── update-claude-md.yml
|
|
145
|
+
|
|
146
|
+
scripts/
|
|
147
|
+
├── extract_patterns.py # Pattern extraction
|
|
148
|
+
└── update_claude_md.py # CLAUDE.md updater
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Success Metrics
|
|
154
|
+
|
|
155
|
+
| Metric | Target | Measurement |
|
|
156
|
+
|--------|--------|-------------|
|
|
157
|
+
| PR CI Pass Rate | >95% | GitHub Actions |
|
|
158
|
+
| Verification Iterations | <2 avg | Command logs |
|
|
159
|
+
| Ralph Mode Completion | >80% tasks | Completion promises |
|
|
160
|
+
| Format Violations | 0 post-save | Git diff checks |
|
|
161
|
+
| CLAUDE.md Freshness | <7 days | Last update date |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Risk Assessment
|
|
166
|
+
|
|
167
|
+
| Risk | Mitigation |
|
|
168
|
+
|------|------------|
|
|
169
|
+
| Stop hook blocks legitimate exits | Provide `/force-exit` override |
|
|
170
|
+
| Ralph mode infinite loops | Max iterations safety (50 default) |
|
|
171
|
+
| Formatter breaks code | Run tests after formatting |
|
|
172
|
+
| Pattern extraction noise | Human review via PR |
|
|
173
|
+
| Performance degradation | Async hooks, time limits |
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## References
|
|
178
|
+
|
|
179
|
+
- Boris Cherny's Claude Code Setup: https://x.com/bcherny/status/2007179832300581177
|
|
180
|
+
- Ralph Wiggum Plugin: https://github.com/anthropics/claude-code/tree/main/plugins/ralph-wiggum
|
|
181
|
+
- Research Document: `docs/boris-cherny-ralph-wiggum-insights.md`
|
|
182
|
+
- Claude Code Best Practices: https://docs.anthropic.com/en/docs/claude-code/best-practices
|