-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun_iterations.sh
More file actions
executable file
·163 lines (125 loc) · 5.5 KB
/
run_iterations.sh
File metadata and controls
executable file
·163 lines (125 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/bin/bash
set -e
WORKSPACE="/Users/faber/entropy/workspace"
OUTPUT="/Users/faber/entropy/output"
ORIGINAL_SPEC="$OUTPUT/original_spec.md"
SPEC="$WORKSPACE/SPEC.md"
START=${1:-4}
END=${2:-10}
for i in $(seq $START $END); do
echo ""
echo "=== Iteration $i/$END ==="
# --- BUILD ---
echo " Building code from spec..."
SPEC_CONTENT=$(cat "$SPEC")
CODE_CONTENT=""
for f in "$WORKSPACE"/*.html "$WORKSPACE"/*.css "$WORKSPACE"/*.js; do
[ -f "$f" ] || continue
fname=$(basename "$f")
CODE_CONTENT+="--- FILE: $fname ---
$(cat "$f")
"
done
BUILDER_PROMPT="Here is the product specification:
<spec>
$SPEC_CONTENT
</spec>
Here is the existing codebase from the previous iteration:
<code>
$CODE_CONTENT
</code>
Rewrite the entire application to match the current spec. You must output ALL files, not just changed ones. Output files using this exact format for each file:
--- FILE: filename.html ---
(file contents)
--- FILE: style.css ---
(file contents)
Plain HTML/CSS/JS only, no frameworks. Every response must include at least one HTML file."
BUILDER_RESPONSE=$(echo "$BUILDER_PROMPT" | claude --print --model sonnet --system-prompt "You are a frontend developer. You build web applications using plain HTML, CSS, and JavaScript only. No frameworks, no libraries, no CDN imports, no build tools. Implement ALL features described in the spec. Do not skip any. Do NOT add features not in the spec. Output files using --- FILE: name --- format." 2>/dev/null)
# Parse and write files
python3 -c "
import re, os, sys
response = sys.stdin.read()
pattern = re.compile(r'^---\s*FILE:\s*(.+?)\s*---\s*$', re.MULTILINE)
splits = pattern.split(response)
count = 0
for i in range(1, len(splits), 2):
name = splits[i].strip()
content = splits[i+1].strip() + '\n' if i+1 < len(splits) else ''
if '..' in name or name.startswith('/'):
continue
fpath = os.path.join('$WORKSPACE', name)
os.makedirs(os.path.dirname(fpath) if os.path.dirname(name) else '$WORKSPACE', exist_ok=True)
with open(fpath, 'w') as f:
f.write(content)
count += 1
if count == 0:
# Fallback: treat as index.html
with open(os.path.join('$WORKSPACE', 'index.html'), 'w') as f:
f.write(response)
count = 1
print(f' Built {count} file(s)')
" <<< "$BUILDER_RESPONSE"
cd "$WORKSPACE" && git add -A && git commit -m "iteration $i: build" --allow-empty && cd /Users/faber/entropy
# --- RE-DOCUMENT ---
echo " Re-documenting from code..."
CODE_CONTENT=""
for f in "$WORKSPACE"/*.html "$WORKSPACE"/*.css "$WORKSPACE"/*.js; do
[ -f "$f" ] || continue
fname=$(basename "$f")
CODE_CONTENT+="--- FILE: $fname ---
$(cat "$f")
"
done
REDOC_PROMPT="Read the following source code and write a product specification documenting what this application does.
<code>
$CODE_CONTENT
</code>
Output only the Markdown spec document, nothing else."
REDOC_RESPONSE=$(echo "$REDOC_PROMPT" | claude --print --model sonnet --system-prompt "You are a technical writer. You document software by reading its source code. Write a product specification describing what the application DOES based solely on the code. Do NOT speculate about intended features that aren't implemented. Do NOT reference the code structure or implementation details. Write from a product perspective: what does a user see and do? Use Markdown with sections and headers. Aim for 200-600 words." 2>/dev/null)
echo "$REDOC_RESPONSE" > "$SPEC"
cd "$WORKSPACE" && git add -A && git commit -m "iteration $i: re-document" --allow-empty && cd /Users/faber/entropy
WORD_COUNT=$(wc -w < "$SPEC" | tr -d ' ')
echo " New spec: $WORD_COUNT words"
# --- JUDGE ---
echo " Judging intent preservation..."
ORIG_SPEC=$(cat "$ORIGINAL_SPEC")
CURR_SPEC=$(cat "$SPEC")
JUDGE_PROMPT="Compare these two specifications:
<original_spec>
$ORIG_SPEC
</original_spec>
<current_spec>
$CURR_SPEC
</current_spec>
Rate how well the current spec preserves the original intent."
JUDGE_RESPONSE=$(echo "$JUDGE_PROMPT" | claude --print --model sonnet --system-prompt "You are an objective analyst comparing two product specifications. You will receive an ORIGINAL spec and a CURRENT spec for the same product. Your job is to assess how well the current spec preserves the original intent.
You must respond in exactly this format (no other text):
INTENT_SCORE: <integer 0-10>
FEATURE_DRIFT: <one sentence describing what was added, removed, or distorted>
SPECIFICITY_SHIFT: <one of: more_generic, more_specific, unchanged>
Scoring guide:
- 10: Current spec perfectly preserves original intent and all features
- 7-9: Core intent preserved, minor feature differences
- 4-6: Recognizably the same product but significant drift
- 1-3: Barely related to original
- 0: Completely unrelated" 2>/dev/null)
echo " $JUDGE_RESPONSE"
# --- METRICS ---
python3 -c "
import metrics, json, re, sys
m = metrics.collect_metrics('workspace', 'workspace/SPEC.md')
m['iteration'] = $i
judge = '''$JUDGE_RESPONSE'''
score_match = re.search(r'INTENT_SCORE:\s*(\d+)', judge)
m['intent_score'] = min(10, max(0, int(score_match.group(1)))) if score_match else 5
drift_match = re.search(r'FEATURE_DRIFT:\s*(.+)', judge)
m['feature_drift'] = drift_match.group(1).strip() if drift_match else 'unparseable'
shift_match = re.search(r'SPECIFICITY_SHIFT:\s*(\S+)', judge)
m['specificity_shift'] = shift_match.group(1).strip() if shift_match else 'unchanged'
m['builder_response_tokens'] = 0
m['documenter_response_tokens'] = 0
print(json.dumps(m))
"
done
echo ""
echo "=== Iterations $START-$END complete ==="