codewhale.history 2.9.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -13
- package/_extract_office.js +158 -0
- package/package.json +4 -2
- package/skills/teach-me/SKILL.md +110 -6
package/README.md
CHANGED
|
@@ -87,6 +87,7 @@ current project. Two independent dimensions across five difficulty levels:
|
|
|
87
87
|
**Content theme** (what it's about):
|
|
88
88
|
- **Standard** (default) — Code comprehension or line reconstruction.
|
|
89
89
|
- **SOLID** (`teach me solid`) — Anti-pattern detection and design restoration.
|
|
90
|
+
- **Spec** (`teach me spec`) — Spec-to-code traceability using office docs as source.
|
|
90
91
|
|
|
91
92
|
| Trigger | Response | Theme | What happens |
|
|
92
93
|
|---------|----------|-------|-------------|
|
|
@@ -94,6 +95,8 @@ current project. Two independent dimensions across five difficulty levels:
|
|
|
94
95
|
| `teach me interactive` | interactive | standard | Lines removed; you restore them |
|
|
95
96
|
| `teach me solid` | passive | solid | Degraded code; you describe fixes |
|
|
96
97
|
| `teach me solid interactive` | interactive | solid | Degraded code; you edit to fix it |
|
|
98
|
+
| `teach me spec` | passive | spec | Spec or code presented; you trace the link |
|
|
99
|
+
| `teach me spec interactive` | interactive | spec | Trace spec to code; you edit code to match |
|
|
97
100
|
|
|
98
101
|
**Triggers:** `teach me` · `quiz me` · `test my knowledge` · `code quiz` ·
|
|
99
102
|
`drill me`
|
|
@@ -106,6 +109,7 @@ current project. Two independent dimensions across five difficulty levels:
|
|
|
106
109
|
| Level | `teach me level 3` or `teach me l3` | Set difficulty 1–5 (default: 3) |
|
|
107
110
|
| Response | `teach me interactive` | Edit the file instead of describing |
|
|
108
111
|
| Theme | `teach me solid` | Anti-pattern detection — fix degraded design |
|
|
112
|
+
| Theme | `teach me spec` | Spec-to-code traceability via office docs |
|
|
109
113
|
| Scope | `teach me services/` | Narrow to a specific file or folder |
|
|
110
114
|
| Concept | `teach me decorators` | Target: decorators, async, generators, context managers, comprehensions, error handling, type hints, threading |
|
|
111
115
|
|
|
@@ -121,24 +125,15 @@ current project. Two independent dimensions across five difficulty levels:
|
|
|
121
125
|
|
|
122
126
|
**Mid-round commands:** `hint` (get a nudge) · `skip` (see the answer) ·
|
|
123
127
|
`next` (draw a new snippet) · `level N` · `easier` · `harder` ·
|
|
124
|
-
`interactive` · `passive` · `solid` · `done` (verify work) · `stop`
|
|
128
|
+
`interactive` · `passive` · `solid` · `spec` · `done` (verify work) · `stop`
|
|
125
129
|
|
|
126
130
|
**At the end** you get a session summary: rounds completed, mode, files covered,
|
|
127
131
|
what you're strong on, what to review, and a suggested next level.
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
| Trigger | What happens |
|
|
132
|
-
|---------|-------------|
|
|
133
|
-
| `teach me solid` | SOLID mode at level 3, passive feedback |
|
|
134
|
-
| `teach me SOLID level 4` | Level 4, passive |
|
|
135
|
-
| `teach me solid interactive` | SOLID mode, you edit the file (not just describe) |
|
|
136
|
-
|
|
137
|
-
**How it works:** The model picks code, rewrites it with deliberate anti-patterns
|
|
133
|
+
In **SOLID theme**: the model rewrites code with deliberate anti-patterns
|
|
138
134
|
(STUPID, WET, god objects, tight coupling), presents the degraded code, and you
|
|
139
|
-
restore good design.
|
|
140
|
-
|
|
141
|
-
with `git checkout` after each round.
|
|
135
|
+
restore good design. Files are always restored with `git checkout` after each
|
|
136
|
+
round.
|
|
142
137
|
|
|
143
138
|
## Requirements
|
|
144
139
|
- Node.js (for the `codewhale-history` command)
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Office Document Text Extractor
|
|
4
|
+
*
|
|
5
|
+
* Extracts plain text from .docx, .pptx, and .xlsx files.
|
|
6
|
+
* Pure Node.js — no external dependencies. Handles ZIP/Open XML internally.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node _extract_office.js <file.docx|pptx|xlsx>
|
|
10
|
+
* codewhale-doc-extract <file.docx|pptx|xlsx>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const zlib = require('zlib');
|
|
15
|
+
|
|
16
|
+
const filePath = process.argv[2];
|
|
17
|
+
if (!filePath) {
|
|
18
|
+
console.error('Usage: codewhale-doc-extract <file.docx|pptx|xlsx>');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const ext = filePath.toLowerCase().split('.').pop();
|
|
23
|
+
const buf = fs.readFileSync(filePath);
|
|
24
|
+
|
|
25
|
+
// ── ZIP parser ─────────────────────────────────────────────────
|
|
26
|
+
function readZip(buffer) {
|
|
27
|
+
const entries = [];
|
|
28
|
+
let offset = 0;
|
|
29
|
+
|
|
30
|
+
while (offset < buffer.length - 4) {
|
|
31
|
+
const sig = buffer.readUInt32LE(offset);
|
|
32
|
+
if (sig !== 0x04034b50) break;
|
|
33
|
+
|
|
34
|
+
const compression = buffer.readUInt16LE(offset + 8);
|
|
35
|
+
const compressedSize = buffer.readUInt32LE(offset + 18);
|
|
36
|
+
const nameLen = buffer.readUInt16LE(offset + 26);
|
|
37
|
+
const extraLen = buffer.readUInt16LE(offset + 28);
|
|
38
|
+
|
|
39
|
+
const name = buffer.toString('utf-8', offset + 30, offset + 30 + nameLen);
|
|
40
|
+
const dataStart = offset + 30 + nameLen + extraLen;
|
|
41
|
+
|
|
42
|
+
let data;
|
|
43
|
+
if (compression === 0) {
|
|
44
|
+
data = buffer.slice(dataStart, dataStart + compressedSize);
|
|
45
|
+
} else if (compression === 8) {
|
|
46
|
+
const raw = buffer.slice(dataStart, dataStart + compressedSize);
|
|
47
|
+
data = zlib.inflateRawSync(raw);
|
|
48
|
+
} else {
|
|
49
|
+
offset = dataStart + compressedSize;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
entries.push({ name, data: data.toString('utf-8') });
|
|
54
|
+
offset = dataStart + compressedSize;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return entries;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ── XML text stripper ──────────────────────────────────────────
|
|
61
|
+
function stripXml(xml) {
|
|
62
|
+
return xml
|
|
63
|
+
.replace(/<[^>]+>/g, ' ')
|
|
64
|
+
.replace(/&/g, '&')
|
|
65
|
+
.replace(/</g, '<')
|
|
66
|
+
.replace(/>/g, '>')
|
|
67
|
+
.replace(/"/g, '"')
|
|
68
|
+
.replace(/'/g, "'")
|
|
69
|
+
.replace(/&#?\w+;/g, ' ')
|
|
70
|
+
.replace(/\s+/g, ' ')
|
|
71
|
+
.trim();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── Format-specific extraction ─────────────────────────────────
|
|
75
|
+
const entries = readZip(buf);
|
|
76
|
+
let text = '';
|
|
77
|
+
|
|
78
|
+
if (ext === 'docx') {
|
|
79
|
+
const doc = entries.find(e => e.name === 'word/document.xml');
|
|
80
|
+
if (doc) text = stripXml(doc.data);
|
|
81
|
+
|
|
82
|
+
for (const e of entries) {
|
|
83
|
+
if (e.name.startsWith('word/header') || e.name.startsWith('word/footer')) {
|
|
84
|
+
text += '\n' + stripXml(e.data);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} else if (ext === 'pptx') {
|
|
88
|
+
const slides = entries
|
|
89
|
+
.filter(e => /^ppt\/slides\/slide\d+\.xml$/.test(e.name))
|
|
90
|
+
.sort((a, b) => {
|
|
91
|
+
const na = parseInt(a.name.match(/slide(\d+)/)[1]);
|
|
92
|
+
const nb = parseInt(b.name.match(/slide(\d+)/)[1]);
|
|
93
|
+
return na - nb;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
for (let i = 0; i < slides.length; i++) {
|
|
97
|
+
text += '\n--- Slide ' + (i + 1) + ' ---\n';
|
|
98
|
+
text += stripXml(slides[i].data) + '\n';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const e of entries) {
|
|
102
|
+
if (e.name.startsWith('ppt/notesSlides/notesSlide')) {
|
|
103
|
+
text += '\n[Notes]\n' + stripXml(e.data) + '\n';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} else if (ext === 'xlsx') {
|
|
107
|
+
const sst = entries.find(e => e.name === 'xl/sharedStrings.xml');
|
|
108
|
+
const strings = sst ? extractSharedStrings(sst.data) : [];
|
|
109
|
+
|
|
110
|
+
const sheets = entries
|
|
111
|
+
.filter(e => /^xl\/worksheets\/sheet\d+\.xml$/.test(e.name))
|
|
112
|
+
.sort((a, b) => {
|
|
113
|
+
const na = parseInt(a.name.match(/sheet(\d+)/)[1]);
|
|
114
|
+
const nb = parseInt(b.name.match(/sheet(\d+)/)[1]);
|
|
115
|
+
return na - nb;
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < sheets.length; i++) {
|
|
119
|
+
text += '\n--- Sheet ' + (i + 1) + ' ---\n';
|
|
120
|
+
text += renderSheet(sheets[i].data, strings) + '\n';
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
console.error('Unsupported format. Use .docx, .pptx, or .xlsx');
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log(text.trim());
|
|
128
|
+
|
|
129
|
+
// ── XLSX helpers ───────────────────────────────────────────────
|
|
130
|
+
function extractSharedStrings(xml) {
|
|
131
|
+
const matches = xml.match(/<si>([\s\S]*?)<\/si>/g) || [];
|
|
132
|
+
return matches.map(si => stripXml(si));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function renderSheet(sheetXml, strings) {
|
|
136
|
+
const rows = sheetXml.match(/<row[\s\S]*?<\/row>/g) || [];
|
|
137
|
+
let output = '';
|
|
138
|
+
for (const row of rows) {
|
|
139
|
+
const cells = row.match(/<c[^>]*>[\s\S]*?<\/c>/g) || [];
|
|
140
|
+
const rowValues = [];
|
|
141
|
+
for (const cell of cells) {
|
|
142
|
+
const tMatch = cell.match(/t="([^"]*)"/);
|
|
143
|
+
const type = tMatch ? tMatch[1] : null;
|
|
144
|
+
const vMatch = cell.match(/<v>([^<]*)<\/v>/);
|
|
145
|
+
if (!vMatch) continue;
|
|
146
|
+
if (type === 's') {
|
|
147
|
+
const idx = parseInt(vMatch[1]);
|
|
148
|
+
rowValues.push(strings[idx] || '');
|
|
149
|
+
} else {
|
|
150
|
+
rowValues.push(vMatch[1]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (rowValues.some(v => v.trim())) {
|
|
154
|
+
output += rowValues.join(' | ') + '\n';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return output;
|
|
158
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codewhale.history",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "CodeWhale utility commands: session history, tool listing, file snapshot, interactive code quiz — global install",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codewhale-history": "./_list_sessions.js",
|
|
7
|
-
"codewhale-tools-install": "./tools-install.js"
|
|
7
|
+
"codewhale-tools-install": "./tools-install.js",
|
|
8
|
+
"codewhale-doc-extract": "./_extract_office.js"
|
|
8
9
|
},
|
|
9
10
|
"files": [
|
|
10
11
|
"_list_sessions.js",
|
|
12
|
+
"_extract_office.js",
|
|
11
13
|
"tools-install.js",
|
|
12
14
|
"README.md",
|
|
13
15
|
"instructions.md",
|
package/skills/teach-me/SKILL.md
CHANGED
|
@@ -12,9 +12,12 @@ current project. Two independent dimensions combine to form each exercise:
|
|
|
12
12
|
- **`passive`** (default) — You describe your answer in the console.
|
|
13
13
|
- **`interactive`** — You edit the actual file, then say `done` for verification.
|
|
14
14
|
|
|
15
|
-
**Content theme** (what the exercise is about — trigger
|
|
15
|
+
**Content theme** (what the exercise is about — trigger keywords `solid`, `spec`):
|
|
16
16
|
- **Standard** (default) — Code comprehension or line reconstruction.
|
|
17
17
|
- **`solid`** / **`SOLID`** — Anti-pattern detection and design restoration.
|
|
18
|
+
- **`spec`** — Spec-to-code traceability. Exercise shapes alternate randomly:
|
|
19
|
+
spec → code (show a requirement, ask what code implements it) or code → spec
|
|
20
|
+
(show code, ask what requirement it satisfies).
|
|
18
21
|
|
|
19
22
|
| Trigger | Response | Theme | What happens |
|
|
20
23
|
|---------|----------|-------|-------------|
|
|
@@ -22,6 +25,8 @@ current project. Two independent dimensions combine to form each exercise:
|
|
|
22
25
|
| `teach me interactive` | interactive | standard | Lines removed from file; you restore them, say `done` |
|
|
23
26
|
| `teach me solid` | passive | solid | Code rewritten with anti-patterns; you describe design fixes |
|
|
24
27
|
| `teach me solid interactive` | interactive | solid | Code rewritten with anti-patterns; you edit the file to restore good design, say `done` |
|
|
28
|
+
| `teach me spec` | passive | spec | Present spec or code; you describe the link between them |
|
|
29
|
+
| `teach me spec interactive` | interactive | spec | Spec-to-code traceability; you edit code to satisfy a spec, say `done` |
|
|
25
30
|
|
|
26
31
|
Level, scope, language, and concept modifiers combine freely with any
|
|
27
32
|
combination above.
|
|
@@ -48,12 +53,14 @@ Optionally followed by modifiers:
|
|
|
48
53
|
`teach me error handling`, `teach me type hints`, `teach me threading`
|
|
49
54
|
- `teach me interactive` — edit the file (instead of describing)
|
|
50
55
|
- `teach me solid` / `teach me SOLID` — anti-pattern restoration theme
|
|
56
|
+
- `teach me spec` — spec-to-code traceability theme
|
|
51
57
|
|
|
52
58
|
Modifiers combine freely: `teach me decorators level 4`,
|
|
53
59
|
`teach me async services/`, `teach me generators l2`,
|
|
54
60
|
`teach me level 2 interactive`, `teach me interactive decorators`,
|
|
55
61
|
`teach me solid level 3`, `teach me SOLID`,
|
|
56
|
-
`teach me solid interactive
|
|
62
|
+
`teach me solid interactive`,
|
|
63
|
+
`teach me spec`, `teach me spec interactive`
|
|
57
64
|
|
|
58
65
|
If no level is specified, default to **level 3** and adjust based on
|
|
59
66
|
performance across rounds.
|
|
@@ -328,6 +335,94 @@ Type `hint` for a clue, `skip` to see the answer, or `stop` to end.
|
|
|
328
335
|
---
|
|
329
336
|
```
|
|
330
337
|
|
|
338
|
+
### 2d. Spec Theme — Spec-to-Code Traceability
|
|
339
|
+
|
|
340
|
+
When content theme is `spec`, the exercise bridges office documents (`.docx`,
|
|
341
|
+
`.pptx`, `.xlsx`) and source code. Each round randomly alternates between two
|
|
342
|
+
exercise shapes.
|
|
343
|
+
|
|
344
|
+
#### Discovery (Spec Theme)
|
|
345
|
+
|
|
346
|
+
In addition to the standard code discovery:
|
|
347
|
+
1. Scan the workspace for `.docx`, `.pptx`, and `.xlsx` files.
|
|
348
|
+
2. Extract text from each using `codewhale-doc-extract <file>` (global bin).
|
|
349
|
+
3. Split extracted text into spec fragments: paragraphs, requirement bullets,
|
|
350
|
+
table rows, slide contents.
|
|
351
|
+
4. Build a combined index: code fragments + spec fragments.
|
|
352
|
+
|
|
353
|
+
#### Exercise Shapes
|
|
354
|
+
|
|
355
|
+
Randomly choose one per round (50/50):
|
|
356
|
+
|
|
357
|
+
**A. Spec → Code** — "Trace forward"
|
|
358
|
+
- Present a spec fragment (a requirement, acceptance criterion, or spec
|
|
359
|
+
paragraph from an office document).
|
|
360
|
+
- Ask: "What code in this project implements this specification?"
|
|
361
|
+
- The user identifies or describes the matching code.
|
|
362
|
+
|
|
363
|
+
**B. Code → Spec** — "Trace backward"
|
|
364
|
+
- Present a code snippet from the project.
|
|
365
|
+
- Ask: "What requirement or specification does this code satisfy?"
|
|
366
|
+
- The user identifies the matching spec from the office documents.
|
|
367
|
+
|
|
368
|
+
The model must verify the link in both directions — does the code actually
|
|
369
|
+
implement the spec, and does the spec actually describe the code?
|
|
370
|
+
|
|
371
|
+
#### Spec Theme Per-Round Flow
|
|
372
|
+
|
|
373
|
+
0. **Snapshot git state.** Run `git status --porcelain` on all source files.
|
|
374
|
+
1. **Pick direction** randomly (A or B). Select a fragment from the
|
|
375
|
+
appropriate index (spec index for A, code index for B).
|
|
376
|
+
2. **Present** the fragment with its source (filename for code, document name
|
|
377
|
+
+ section for specs).
|
|
378
|
+
3. **Instruct** (depends on response mode):
|
|
379
|
+
- *Passive:* "Trace the link. What [code implements this spec / spec does
|
|
380
|
+
this code satisfy]? Describe in detail."
|
|
381
|
+
- *Interactive:* Same prompt, but also: "If the link is broken or missing,
|
|
382
|
+
edit the code to correctly implement the spec. Say `done` when ready."
|
|
383
|
+
For interactive: run `//snapshot on` first if the workspace is NOT a git
|
|
384
|
+
repo.
|
|
385
|
+
4. **Wait.** Do not evaluate until the user signals completion.
|
|
386
|
+
5. **Evaluate** (depends on response mode):
|
|
387
|
+
- *Passive:* Assess the user's trace — did they correctly identify the
|
|
388
|
+
link? Is their reasoning sound?
|
|
389
|
+
- *Interactive:* Re-read the modified files. Compare against the spec.
|
|
390
|
+
Does the code now correctly implement the requirement?
|
|
391
|
+
6. **Feedback** — structure:
|
|
392
|
+
```
|
|
393
|
+
**Trace accuracy:** [Correct / Partially correct / Incorrect]
|
|
394
|
+
**What you got right:** [the link they correctly identified]
|
|
395
|
+
**What you missed:** [missed connections between spec and code]
|
|
396
|
+
```
|
|
397
|
+
7. **Restore** (interactive only). If files were modified: `git checkout -- <file>`.
|
|
398
|
+
If not a git repo, `//snapshot off` to stop backing up.
|
|
399
|
+
|
|
400
|
+
#### Thinking Suppression (Spec Theme)
|
|
401
|
+
|
|
402
|
+
Use **Skip** thinking during selection and presentation (steps 1–3). Resume
|
|
403
|
+
normal depth at step 4. Never reveal the correct trace link in reasoning.
|
|
404
|
+
|
|
405
|
+
#### Spec Theme Presentation Format
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
---
|
|
409
|
+
## Round N — Level X · passive · spec | Spec → Code
|
|
410
|
+
|
|
411
|
+
**From:** `QA Cinemas Requirements.pptx` — Slide 4, "Website Requirements (1)"
|
|
412
|
+
|
|
413
|
+
> The QA Cinemas site needs a home page. The home page shall: Be generally
|
|
414
|
+
> attractive. Be the default for the entire site. Allow site users to navigate
|
|
415
|
+
> to other areas of the site. Have a picture or graphic evocative of the
|
|
416
|
+
> movies or the cinema on it.
|
|
417
|
+
|
|
418
|
+
**Your turn:** (Passive) What code in this project implements the QA Cinemas
|
|
419
|
+
home page requirement? Trace the link — describe which file(s) and how they
|
|
420
|
+
satisfy these criteria.
|
|
421
|
+
|
|
422
|
+
Type `hint` for a clue, `skip` to see the answer, or `stop` to end.
|
|
423
|
+
---
|
|
424
|
+
```
|
|
425
|
+
|
|
331
426
|
### 3. Presentation — Show the Snippet
|
|
332
427
|
|
|
333
428
|
For each round, present the snippet with its filename:
|
|
@@ -565,14 +660,15 @@ nailed everything at-level, say so and highlight the nuance they caught.
|
|
|
565
660
|
| `harder` | Increase level by 1 (maximum 5). |
|
|
566
661
|
| `interactive` | Switch to interactive (reconstruction) mode for subsequent rounds. |
|
|
567
662
|
| `passive` | Switch to passive (explanation) mode for subsequent rounds. |
|
|
568
|
-
| `solid` / `SOLID` | Switch to SOLID (anti-pattern reconstruction)
|
|
569
|
-
| `
|
|
663
|
+
| `solid` / `SOLID` | Switch to SOLID (anti-pattern reconstruction) theme for subsequent rounds. |
|
|
664
|
+
| `spec` | Switch to spec (spec-to-code traceability) theme for subsequent rounds. |
|
|
665
|
+
| `done` / `check my work` | (Interactive/SOLID/Spec mode) Signal that work is complete. Triggers verification. |
|
|
570
666
|
| `stop` / `end` | End session. Deliver summary. |
|
|
571
667
|
|
|
572
668
|
### 5. Loop — Keep Going
|
|
573
669
|
|
|
574
670
|
After a successful evaluation or a `next` skip, ask:
|
|
575
|
-
"Another round? (yes / no / level N / interactive / passive / solid / stop)"
|
|
671
|
+
"Another round? (yes / no / level N / interactive / passive / solid / spec / stop)"
|
|
576
672
|
|
|
577
673
|
After a strike-3 reveal, do **not** ask — proceed directly to the next
|
|
578
674
|
round with:
|
|
@@ -641,8 +737,11 @@ criteria for the Mechanics axis:
|
|
|
641
737
|
restore the original lines manually via `edit_file` instead and warn the user.
|
|
642
738
|
- **Restore on session end.** When the session ends, check whether any files
|
|
643
739
|
still contain `# ... N lines removed ...` placeholders or deconstructed
|
|
644
|
-
code from interactive/SOLID mode. If so, restore them with
|
|
740
|
+
code from interactive/SOLID/spec mode. If so, restore them with
|
|
645
741
|
`git checkout -- <file>` (or `edit_file` if pre-existing changes).
|
|
742
|
+
- **Spec theme snapshot.** In interactive+spec mode, run `//snapshot on`
|
|
743
|
+
before file edits if the workspace is not a git repo. Run `//snapshot off`
|
|
744
|
+
after restoration.
|
|
646
745
|
|
|
647
746
|
## Verification
|
|
648
747
|
|
|
@@ -664,3 +763,8 @@ After each round, confirm:
|
|
|
664
763
|
- (SOLID mode) Individual anti-patterns were NOT annotated or revealed before evaluation
|
|
665
764
|
- (SOLID mode) The file was re-read before evaluating the user's restoration
|
|
666
765
|
- (SOLID mode) Deconstructed files were restored with `git checkout` on round end
|
|
766
|
+
- (Spec theme) Office docs were scanned and extracted during discovery
|
|
767
|
+
- (Spec theme) Exercise direction (spec→code or code→spec) was chosen randomly each round
|
|
768
|
+
- (Spec theme) The trace link was verified in both directions by the model
|
|
769
|
+
- (Spec theme) Interactive mode ran `//snapshot on/off` for non-git workspaces
|
|
770
|
+
- (Spec theme) Modified files were restored after the round
|