spec-and-loop 2.1.1 → 3.0.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.
@@ -0,0 +1,564 @@
1
+ # Writing Ralph-Friendly OpenSpec Tasks
2
+
3
+ An actionable guide to shaping tasks so a Ralph Wiggum–style loop (fresh-session, re-reads prompt and repo state each iteration, uses objective backpressure) can make steady progress without getting stuck on ambiguity, hidden policy, or missing verification.
4
+
5
+ This guide is organized so you can act first and read rationale second:
6
+
7
+ 1. [Quick reference: the task template](#quick-reference-the-task-template)
8
+ 2. [Quick reference: how to order tasks](#quick-reference-how-to-order-tasks)
9
+ 3. [Quick reference: authoring recipe](#quick-reference-authoring-recipe)
10
+ 4. [Task sizing and splitting](#task-sizing-and-splitting)
11
+ 5. [Worked examples: good vs. bad tasks](#worked-examples-good-vs-bad-tasks)
12
+ 6. [Quality gates and baselines](#quality-gates-and-baselines)
13
+ 7. [Human handoffs and operator-only work](#human-handoffs-and-operator-only-work)
14
+ 8. [The surrounding artifact package](#the-surrounding-artifact-package)
15
+ 9. [`prd.json` specifics](#prdjson-specifics)
16
+ 10. [Authoring checklist](#authoring-checklist)
17
+ 11. [Background and rationale](#background-and-rationale)
18
+ 12. [Source notes](#source-notes)
19
+
20
+ ---
21
+
22
+ ## Quick reference: the task template
23
+
24
+ Every Ralph-friendly task checkbox in `tasks.md` should fit this shape:
25
+
26
+ ```markdown
27
+ - [ ] **<short imperative outcome>**
28
+ - Scope: <1 subsystem or tightly related file cluster; name the primary files>
29
+ - Change: <what behavior, data, or contract becomes true after this task>
30
+ - Done when:
31
+ - <observable change 1, tied to code/data/doc>
32
+ - <verifier command or selector with expected result>
33
+ - <optional second verifier if it is in the same cluster>
34
+ - Stop and hand off if:
35
+ - <concrete blocker condition, e.g. "a required-clean gate regresses">
36
+ - <concrete ambiguity condition, e.g. "spec disagrees with design">
37
+ ```
38
+
39
+ Rules this template enforces:
40
+
41
+ - **One dominant outcome.** The bold title is a single behavior slice, not a list.
42
+ - **One file cluster.** Scope names the area so the loop does not go hunting.
43
+ - **Objective "done".** Every `Done when` bullet is either an observable artifact change or a runnable check with a named expected result. No soft verbs (`ensure`, `validate`, `support`, `keep`) without an attached observable.
44
+ - **Explicit stop conditions.** The loop has written permission to halt, so it does not improvise.
45
+
46
+ A one-line prose version for the title and change, useful when drafting:
47
+
48
+ > Change X behavior in Y area so that Z becomes true. Verify by running C and confirming D. Stop and hand off if E.
49
+
50
+ If you need "and" twice in that first sentence, you are probably hiding a split point.
51
+
52
+ ---
53
+
54
+ ## Quick reference: how to order tasks
55
+
56
+ When in doubt, arrange tasks from shared contract outward to user-facing surfaces:
57
+
58
+ 1. **Pre-flight baseline.** Run every quality gate a later task requires to pass. Record the output. This is the only way later iterations can distinguish regressions from pre-existing failures. See [quality gates](#quality-gates-and-baselines).
59
+ 2. **Freeze shared contracts and prerequisites.** Types, interfaces, registration points, ownership boundaries.
60
+ 3. **Freeze typed data, config, schemas.** Centralize the data a later surface task would otherwise have to rediscover.
61
+ 4. **Implement one user-facing surface at a time.** One route, one component family, or one workflow per task.
62
+ 5. **Wire shared emitters and cross-links.** Navigation, shared shells, cross-references, anything that spans surfaces.
63
+ 6. **Run final integrated quality gates.** A dedicated task that runs the full suite and is allowed to be a hard stop.
64
+
65
+ Why this ordering: early tasks reduce ambiguity for later ones. A route task that can trust a frozen typed-data contract is dramatically smaller and safer than one that must invent the contract while rendering the page.
66
+
67
+ Do **not** make the agent infer the dependency graph. Order the checkboxes in `tasks.md` as written, and if two tasks are independent, say so explicitly.
68
+
69
+ ---
70
+
71
+ ## Quick reference: authoring recipe
72
+
73
+ 1. **Draft behavior slices, not file edits.** "Freeze X contract," "centralize Y data," "implement Z surface." Never "edit `file-a`."
74
+ 2. **Size against the smallest model you expect to run the loop.** If you expect a smaller model or heavy context reload, bias one size smaller than your strongest-model plan. See [sizing profiles](#two-sizing-profiles).
75
+ 3. **For each candidate task, count `V`, `S`, `C`, `P`:**
76
+ - `V` = independent verification clusters
77
+ - `S` = independent subsystems or file clusters
78
+ - `C` = clean stopping points that would leave the repo reviewable
79
+ - `P` = unresolved policy or design questions
80
+ 4. **If `P > 0`, stop.** Fix the design or spec first. Do not encode unresolved policy as a task.
81
+ 5. **If `V`, `S`, or `C` is meaningfully `> 1`, split.** Default lightweight split target: `recommended subtasks = max(V, C)`, `+1` if the task mixes foundation with feature work, `+1` if it mixes a user-facing surface with shared cross-surface wiring.
82
+ 6. **Stop splitting before tasks become file chores.** A child task that has no standalone verifier or clean stopping point has been split too far.
83
+ 7. **Apply the [task template](#quick-reference-the-task-template) to each final checkbox.**
84
+ 8. **Order the final list** using the [contract-to-surface pattern](#quick-reference-how-to-order-tasks), with a pre-flight baseline task at the top if any later task requires a gate to be clean.
85
+
86
+ One-line rule of thumb:
87
+
88
+ **Keep splitting until each checkbox has one dominant verifier and one clean stop point, then stop.**
89
+
90
+ ---
91
+
92
+ ## Task sizing and splitting
93
+
94
+ Task size is **harness-relative**. The correct unit is the largest coherent slice that still fits the actual context budget of the loop you plan to run.
95
+
96
+ - Too broad: agent makes hidden design decisions and thrashes.
97
+ - Too granular: loop wastes iterations on bookkeeping and repeated context reload.
98
+ - Too context-heavy: task is semantically valid, but the model spends the iteration reloading unrelated facts.
99
+ - Right: one coherent behavior slice, one main risk, one main verification cluster, one honest stopping point.
100
+
101
+ ### Signs a task is too large — split it
102
+
103
+ - Spans more than one independent file cluster or subsystem.
104
+ - Has more than one independent verification cluster.
105
+ - Mixes foundation work and feature work in one checkbox.
106
+ - Contains more than one obvious mergeable stopping point.
107
+ - Requires the agent to hold many unrelated policy rules in working memory.
108
+ - Likely to trigger broad search, broad refactor, and broad validation in the same iteration.
109
+
110
+ ### Signs a task is too small — merge it
111
+
112
+ - Touches the same small file cluster as its neighbor.
113
+ - Shares the same main verification command as its neighbor.
114
+ - The first half does not produce a meaningful checkpoint on its own.
115
+ - Splitting only creates bookkeeping churn.
116
+ - Exists only so the next checkbox can finish it.
117
+ - Its only proof is "the next task worked."
118
+
119
+ ### Two sizing profiles
120
+
121
+ Pick one explicitly before you start writing tasks.
122
+
123
+ **Medium profile** — use when the loop reloads the full artifact pack cleanly, the model is strong, and the repo area is familiar:
124
+
125
+ - one dominant outcome, one dominant risk
126
+ - one main code or data surface
127
+ - one main verification cluster
128
+ - roughly 2–5 primary files in one area
129
+ - 1–2 focused verification commands or selectors
130
+ - 3–7 `Done when` bullets
131
+
132
+ **Lightweight profile** — use when you expect smaller models, heavy per-iteration context reload, broad/unfamiliar repo area, or want more loop checkpoints:
133
+
134
+ - one dominant outcome, one dominant verification cluster
135
+ - one subsystem or tightly related file cluster
136
+ - one clean stopping point that would still be reviewable if the loop stopped there
137
+ - roughly 1–3 primary files (sometimes 4 if same route or subsystem)
138
+ - ideally 1 focused verification command or selector (occasionally 2)
139
+ - 2–5 `Done when` bullets
140
+
141
+ ### Split / merge test
142
+
143
+ Before finalizing a checkbox, ask:
144
+
145
+ 1. If the loop stopped halfway through this item, would the repo be in a clean, reviewable state?
146
+ 2. Would I know exactly which verification command proves this half is done?
147
+ 3. Does this checkbox have one dominant risk, or several unrelated ones?
148
+
149
+ Interpretation:
150
+
151
+ - If answers 1 and 2 are "yes," there is a valid split point.
152
+ - If answer 3 is "several," the task is probably too large.
153
+ - If none of the halves would be meaningful on their own, the task is already about right.
154
+
155
+ ### Can you triple the task count?
156
+
157
+ Yes, sometimes — when the extra checkboxes come from real checkpoints, not mechanical crumbs.
158
+
159
+ Good reasons the count grows: a previous checkbox actually contained 2–3 independent verification clusters; a checkbox mixed contract freezing with feature work; a smaller model means medium tasks are no longer comfortable in one session; you want explicit clean stop points for long-running loops.
160
+
161
+ Bad reasons: turning one coherent change into a sequence of file chores; splitting edits that share the same verifier and stopping point; separate tasks for imports, renames, or tiny mechanical follow-through; doc-only subtasks that do not freeze an independent contract.
162
+
163
+ ---
164
+
165
+ ## Worked examples: good vs. bad tasks
166
+
167
+ ### Example 1: too large vs. split
168
+
169
+ **Too large** — mixes three independent contracts in one checkbox:
170
+
171
+ ```markdown
172
+ - [ ] Freeze the bootstrap contract in code, tests, and docs
173
+ ```
174
+
175
+ **Better** — three tasks, each with its own verifier and stop point:
176
+
177
+ ```markdown
178
+ - [ ] **Freeze Atmosphere CSS ownership**
179
+ - Scope: `src/styles/atmosphere/*`, `tailwind.config.*`
180
+ - Change: Atmosphere is the sole owner of the listed tokens; Harbor no longer redefines them.
181
+ - Done when:
182
+ - `rg "atm-color-" src/styles/harbor` returns no matches
183
+ - `npx tsc --noEmit` exits 0
184
+ - Stop and hand off if: a required token is owned by both systems and the design does not say which wins.
185
+
186
+ - [ ] **Freeze Harbor registration and TSX integration**
187
+ - Scope: `src/components/harbor-bootstrap.tsx`, `src/types/harbor.d.ts`
188
+ - Change: Harbor components are registered once at boot and typed for TSX usage.
189
+ - Done when:
190
+ - `rg "registerHarbor" src` returns exactly one call site
191
+ - `npm test -- harbor-bootstrap` passes
192
+ - Stop and hand off if: more than one registration site is required by a consumer.
193
+
194
+ - [ ] **Freeze contributor docs for the chosen authoring model**
195
+ - Scope: `docs/contributing/components.md`
196
+ - Change: Docs describe the frozen Atmosphere+Harbor model and link to the two tasks above.
197
+ - Done when:
198
+ - Doc file exists and lists both ownership rules
199
+ - `npm run lint:docs` exits 0
200
+ - Stop and hand off if: docs would need to describe a policy not yet settled in `design.md`.
201
+ ```
202
+
203
+ ### Example 2: too small vs. merged
204
+
205
+ **Too small** — two chores with no standalone checkpoint:
206
+
207
+ ```markdown
208
+ - [ ] Add `import { formatDate } from './date'` to `ReleaseCard.tsx`
209
+ - [ ] Use `formatDate` in the `ReleaseCard` publish timestamp
210
+ ```
211
+
212
+ **Better** — one task with a real outcome and verifier:
213
+
214
+ ```markdown
215
+ - [ ] **Format ReleaseCard publish timestamp via the shared `formatDate` helper**
216
+ - Scope: `src/components/ReleaseCard.tsx`
217
+ - Change: ReleaseCard renders timestamps through the shared helper instead of inline formatting.
218
+ - Done when:
219
+ - `rg "toLocaleDateString" src/components/ReleaseCard.tsx` returns no matches
220
+ - `npm test -- ReleaseCard` passes
221
+ - Stop and hand off if: `formatDate` does not cover a required locale used by fixtures.
222
+ ```
223
+
224
+ ### Example 3: soft verbs vs. observable "done"
225
+
226
+ **Bad** — vague verbs, no verifier:
227
+
228
+ ```markdown
229
+ - [ ] Ensure support for tenant-scoped promotion
230
+ ```
231
+
232
+ **Better** — outcome, verifier, and stop condition are explicit:
233
+
234
+ ```markdown
235
+ - [ ] **Refuse promotion when a staged tenant version has missing required rows**
236
+ - Scope: `src/ingestion/promote.py`, `tests/unit/test_promote.py`
237
+ - Change: `promote` exits non-zero and leaves the active version unchanged when required staged rows are missing.
238
+ - Done when:
239
+ - New test `test_promote_refuses_missing_rows` passes
240
+ - `pytest tests/unit/test_promote.py` exits 0
241
+ - Active version in the fixture DB is unchanged after the failed promote
242
+ - Stop and hand off if: the set of "required rows" is not defined in `design.md`.
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Quality gates and baselines
248
+
249
+ The single most common quality failure in observed Ralph runs: a task has a `Done when: npm test exits 0` bullet, the test fails, and the loop marks the task complete anyway with a rationalization note explaining why the failure is "unrelated" or "pre-existing."
250
+
251
+ The rule:
252
+
253
+ **If a `Done when` check fails, the task is not done. The loop must stop and report the failure rather than reclassify the gate as inapplicable.**
254
+
255
+ The only legitimate exception is a check that the task itself explicitly categorizes as a known pre-existing failure — and that categorization must be made by the author at task-writing time, not by the agent at execution time.
256
+
257
+ ### "Pre-existing" requires a before-baseline
258
+
259
+ "Pre-existing and unrelated" is only valid if there is documented evidence that the check was already failing *before this task's code changes ran*. Without a before-run, any test failure could equally be a regression introduced by this task.
260
+
261
+ A common failure mode:
262
+
263
+ 1. Task A adds code. Its `Done when` list only says `npx tsc --noEmit exits 0`. The loop runs `tsc`, notes it is blocked by pre-existing errors, documents that, and moves on. `npm test` is never run.
264
+ 2. Task B's `Done when` list says `npm test exits 0`. The loop runs `npm test` for the first time. It fails.
265
+ 3. The loop classifies the failure as "pre-existing" because it "looks unrelated," even though no one verified the test suite was clean before Task A.
266
+
267
+ ### Always include a pre-flight baseline task
268
+
269
+ When a chain of tasks collectively produces a feature and any task in the chain requires a quality gate to be clean, the first task in the chain should be a dedicated pre-flight that:
270
+
271
+ - Runs every gate later tasks require.
272
+ - Records the exact outputs (file paths, exit codes, failing test names).
273
+ - Documents any gates already failing and why.
274
+ - Names the baseline file so later tasks can reference it when distinguishing regressions.
275
+
276
+ Template:
277
+
278
+ ```markdown
279
+ - [ ] **Pre-flight: record quality gate baselines for this change**
280
+ - Scope: no code edits
281
+ - Change: Capture the current state of all gates later tasks require.
282
+ - Done when:
283
+ - `.ralph/baselines/<change>-tsc.txt` exists with full `npx tsc --noEmit` output
284
+ - `.ralph/baselines/<change>-test.txt` exists with full `npm test` output
285
+ - `.ralph/baselines/<change>-readme.md` lists which gates passed, which failed, and for failing gates the exact failing identifiers
286
+ - Stop and hand off if: any gate behavior is nondeterministic across two consecutive runs (flaky baseline is not a baseline).
287
+ ```
288
+
289
+ ### Name known-broken vs. required-clean validators
290
+
291
+ A subtler failure: the loop correctly learns to document and continue when `npx tsc --noEmit` fails due to known pre-existing repo errors. Then it applies the same permissive reasoning to `npm test`, which was supposed to be clean.
292
+
293
+ Loop instructions (prompt or wrapper) must explicitly list both categories:
294
+
295
+ - **Known-broken validators**: named by command or pattern. Loop may document failures and continue **only for these**.
296
+ - **Required-clean validators**: named explicitly. Failures are hard blockers with no exception, regardless of how the failure looks.
297
+
298
+ If only one list is named, the loop will generalize permissive behavior across all gates.
299
+
300
+ ### Screenshots and large binary assets
301
+
302
+ Visual verification tasks that use Chrome DevTools MCP or Figma MCP screenshots can exceed provider context limits when the images are read back into working context. In observed runs this caused `failed to parse request` errors mid-iteration, forcing compaction and restart from a summary. Compaction discards intermediate state and can cause the loop to misclassify prior task completion.
303
+
304
+ Rules for visual tasks:
305
+
306
+ - Save screenshots to a repo-local file path; record the path in task notes.
307
+ - Do not re-read screenshot files into loop context after capture.
308
+ - For Chrome DevTools screenshots, use `filePath` to save and only record the path.
309
+ - Scope Figma MCP calls narrowly: use `excludeScreenshot: true` for structural inspection.
310
+ - If a task requires both a code change and a visual verification, split them: one task for the code change (verified by `tsc`/`npm test`), one for the visual check (verified by screenshot path capture and manual or scripted comparison).
311
+
312
+ ---
313
+
314
+ ## Human handoffs and operator-only work
315
+
316
+ Stage rollout validation, production-only checks, approvals, privileged access — these are not autonomous loop tasks.
317
+
318
+ Rules:
319
+
320
+ - Keep them documented in the artifact pack.
321
+ - Put them in a dedicated `Human Handoff` or `Operator Handoff` section of `tasks.md` or in `proposal.md`.
322
+ - Keep them **outside the checkbox path the loop consumes**. If your loop reads `- [ ]` items, operator items must not use that marker, or must live under a heading the loop instructions tell the agent to skip.
323
+ - Do not rely on "we discussed this in chat." The handoff must live in a durable file.
324
+
325
+ If the loop cannot honestly complete an item without a human or a protected environment, it should not be a normal task.
326
+
327
+ ---
328
+
329
+ ## The surrounding artifact package
330
+
331
+ A task list does not stand alone. Ralph reloads a package of artifacts each iteration. Each file answers a different question:
332
+
333
+ | Question | File | What it contains |
334
+ | -------- | ---- | ---------------- |
335
+ | Why are we doing this? | `proposal.md` | Problem, value, scope, non-goals, rollout boundaries, operator impact |
336
+ | What must be true when we are done? | `specs/**/spec.md` | Required behaviors, failure cases, scenarios, first-rollout vs. deferred |
337
+ | How should the system behave internally? | `design.md` | Algorithms, config shapes, failure semantics, compatibility, retention math, handoff flow |
338
+ | What is the next safe increment? | `tasks.md` | Ordered checkboxes using the task template above |
339
+ | How should the loop operate? | Loop prompt / wrapper | Reload rules, one-task-per-iteration, validator categories, stop conditions |
340
+
341
+ Authoring rules:
342
+
343
+ - **Resolve or explicitly defer policy before writing tasks.** Phrases like "may be shared or tenant-specific," "one option is," or "could support later" are fine while exploring; they are blockers once the loop starts. Resolve algorithms, fallback behavior, retention math, config shape, failure taxonomy, and compatibility-window behavior in `design.md`.
344
+ - **Specs must be deterministic.** If two good implementers could read the spec and make materially different choices, the spec is not loop-safe yet.
345
+ - **If a dedicated coverage artifact exists** (such as a `figma-route-map.md`), route and shared-surface tasks should reuse it as the durable source of truth instead of rediscovering coverage each iteration.
346
+ - **Run with full OpenSpec context when available.** Repo guidance favors `./scripts/ralph-run.sh tasks <change>` over raw `tasks.md` mode because `opsx-apply` provides the agent with a manifest of OpenSpec artifact paths (`## OpenSpec Artifacts`) so the agent can read proposal, design, and specs as needed each iteration. If you run raw `prd.json` or raw `tasks.md` mode, push more detail down into each item because the companion docs will not be listed in the manifest.
347
+
348
+ ### Loop-prompt / wrapper instructions
349
+
350
+ At minimum, the loop prompt must tell the agent to:
351
+
352
+ - Read the OpenSpec artifacts listed in `## OpenSpec Artifacts` (proposal, design, specs) before implementing the current task.
353
+ - Inspect prior iteration state before starting new work.
354
+ - Implement exactly one task per iteration.
355
+ - Run the exact validators relevant to that task.
356
+ - Mark progress **only** after verification succeeds.
357
+ - Stop and request help on ambiguity, contradictions, missing dependencies, or unresolved failures.
358
+ - Not invent new requirements or silently redefine "done."
359
+ - Preserve human handoff items as handoff items.
360
+
361
+ Additional critical rules to state explicitly:
362
+
363
+ - A `Done when` check failure is a hard blocker. Do not reclassify a failing gate as "pre-existing" or "unrelated" unless the task itself documents that pre-existing failure with explicit before-run evidence.
364
+ - Distinguish known-broken validators (document and continue) from required-clean validators (hard stop). Name both categories. Do not generalize permissive behavior from one to the other.
365
+ - Before writing any code in a task requiring quality gates to pass, run those gates and record the baseline. A failure seen after code changes but not in the baseline is a regression and a hard stop.
366
+ - Do not read large binary assets back into working context after capturing them. Save to disk, record the path, move on.
367
+ - Use portable shell constructs. In zsh, `status` is read-only; use `$?` directly rather than `status=$?`.
368
+
369
+ ---
370
+
371
+ ## `prd.json` specifics
372
+
373
+ The local JSON template is intentionally minimal:
374
+
375
+ ```json
376
+ {
377
+ "features": [
378
+ {
379
+ "category": "functional",
380
+ "description": "Description of the feature requirement",
381
+ "steps": ["Step 1 to verify", "Step 2 to verify"],
382
+ "passes": false
383
+ }
384
+ ]
385
+ }
386
+ ```
387
+
388
+ Because the schema is small, most of the real quality comes from how `description` and `steps` are written.
389
+
390
+ Rules:
391
+
392
+ 1. **Treat `description` and `steps` as immutable truth.** The loop updates only `passes: false -> true`. If the requirement is wrong, a human edits it deliberately.
393
+ 2. **Each feature is a behavior slice, not a file chore.** "Tenant-scoped promotion refuses to activate when required staged rows are missing," not "edit `promote.py`."
394
+ 3. **Write `steps` as verification steps.** Observable, ordered, testable. Answer: how to observe the behavior, what to run, what to compare, what must be true for `passes` to become `true`.
395
+ 4. **Each feature fits in one session.** If it needs multiple unrelated edits, multiple policy decisions, and several different verification modes, split it.
396
+ 5. **Encode quality gates in `steps` or the loop prompt.** The schema does not carry them separately.
397
+ 6. **Prefer end-to-end verification over code-only.** Unit tests passing does not prove the feature works end-to-end. For UI or workflow changes, include steps that simulate a real user path or a realistic system check.
398
+ 7. **Manual/operator items go elsewhere.** Do not put stage validation or approvals into the autonomous JSON list unless clearly marked and excluded from execution.
399
+ 8. **Order by dependency.** Schema and primitives first, then behavior, then integration, then docs. Do not make the agent infer the graph.
400
+ 9. **Do not encode unresolved design choices as feature items.** "Decide whether cleanup is shared or tenant-specific" is a design question, not an implementation feature.
401
+ 10. **Keep JSON concise; move rationale to companion docs.** JSON carries execution truth; motivation, scope, architecture, and handoffs live in `proposal.md` and `design.md`.
402
+
403
+ Good local `prd.json` item:
404
+
405
+ ```json
406
+ {
407
+ "category": "ingestion",
408
+ "description": "Standalone promote refuses to activate a staged tenant version when required staged rows are missing",
409
+ "steps": [
410
+ "Create or identify a tenant with a staged target version but missing required staged rows",
411
+ "Run the standalone promote path for that tenant",
412
+ "Verify the command exits non-zero or returns the documented failure outcome",
413
+ "Verify tenant active version is unchanged",
414
+ "Run the relevant test selector and confirm it passes"
415
+ ],
416
+ "passes": false
417
+ }
418
+ ```
419
+
420
+ Why this works: outcome-based description, deterministic steps, explicit negative behavior, includes verification, no hidden product decision.
421
+
422
+ ---
423
+
424
+ ## Authoring checklist
425
+
426
+ Before calling an OpenSpec change "Ralph-friendly," confirm all of these:
427
+
428
+ ### Artifact package
429
+
430
+ - [ ] `proposal.md` states scope, non-goals, and first-rollout boundaries.
431
+ - [ ] `design.md` does not leave core policy choices unresolved.
432
+ - [ ] Specs are specific enough that two implementers would not make materially different choices.
433
+ - [ ] Human/operator work is documented outside the autonomous checkbox path.
434
+ - [ ] The artifacts on disk contain all critical guidance that a fresh session needs.
435
+
436
+ ### Task shape
437
+
438
+ - [ ] Each task uses the [task template](#quick-reference-the-task-template) (outcome title, scope, change, `Done when`, stop condition).
439
+ - [ ] Each task is atomic in the semantic sense, not merely tiny.
440
+ - [ ] Each task has one dominant outcome and one dominant verification cluster.
441
+ - [ ] Each task size matches the smallest model/harness expected to run it.
442
+ - [ ] No checkbox contains two obvious mergeable checkpoints that could be verified independently.
443
+ - [ ] If using a lightweight profile, the higher task count comes from real checkpoints rather than file-chore fragmentation.
444
+ - [ ] No task has been split so far that it loses its own meaningful verifier or clean stopping point.
445
+ - [ ] Each task has an explicit, runnable verification target.
446
+
447
+ ### Ordering and dependencies
448
+
449
+ - [ ] Tasks are ordered contract → data → surface → shared wiring → final gates.
450
+ - [ ] No task depends on stage/prod/manual access unless it is explicitly a handoff item.
451
+ - [ ] Any task chain that requires `npm test` or browser tests to pass in a later task includes a pre-flight quality gate task at the start that records baseline output.
452
+
453
+ ### Quality gates
454
+
455
+ - [ ] No task's `Done when` requires a gate to pass without the loop instructions making clear that gate failure is a hard stop.
456
+ - [ ] The loop instructions name known-broken validators (document and continue) and required-clean validators (hard stop), and forbid generalizing between them.
457
+ - [ ] Visual verification tasks save outputs to file paths and do not re-read large binary content back into loop context.
458
+ - [ ] Tasks requiring both a code change and a visual screenshot comparison are split into two tasks if combining them would risk context overflow.
459
+
460
+ ### `prd.json` (if used)
461
+
462
+ - [ ] The loop is instructed to modify only `passes`.
463
+ - [ ] `description` and `steps` are outcome-based and deterministic.
464
+ - [ ] Manual/operator items are excluded from the autonomous list.
465
+
466
+ ### Anti-patterns to avoid
467
+
468
+ - Vague verbs (`ensure`, `support`, `validate`) with no observable output.
469
+ - Asking the loop to decide policy mid-implementation.
470
+ - Mixing implementation, rollout, and manual validation in one checkbox.
471
+ - Splitting one migration or tightly related refactor into tiny loop iterations with no independent verification point.
472
+ - Hiding critical instructions only in chat history.
473
+ - Letting the agent rewrite feature definitions instead of only updating status.
474
+ - Declaring done from unit tests alone when the real behavior is end-to-end.
475
+ - Leaving "maybe this, maybe that" wording in design or proposal once implementation is about to start.
476
+ - Marking a task complete when a `Done when` check failed, with a rationalization note explaining why the failure "does not count."
477
+ - Classifying a failing quality gate as "pre-existing" without a documented before-baseline.
478
+ - Running `tsc` during code-writing tasks but not `npm test`, then running `npm test` for the first time in a later task and treating its failure as pre-existing.
479
+ - Generalizing the permissive "document and continue" pattern from a known-broken validator to validators that should be clean.
480
+ - Reading large binary assets back into working context after capture.
481
+ - Using reserved or read-only zsh variable names like `status`.
482
+
483
+ ---
484
+
485
+ ## Background and rationale
486
+
487
+ This section preserves the reasoning behind the rules above. If the quick-reference sections answer your authoring question, you can skip it.
488
+
489
+ ### Why Ralph loops depend on artifacts, not chat
490
+
491
+ Ralph loops work because each iteration starts fresh, re-reads the prompt and repo state, and uses objective backpressure (tests, typechecks, render checks, browser checks). The loop is only as good as the artifacts it reloads every time.
492
+
493
+ The most important principle:
494
+
495
+ **Ralph does not want the smallest textual tasks. Ralph wants the largest coherent task that is still unambiguous, objectively verifiable, and comfortably completable in one agent session.**
496
+
497
+ Task size is harness-relative: with a strong model and disciplined full-artifact reload, medium tasks are often best; with a smaller model, noisy tool output, or heavy context reload, the same task may be too large. The correct unit is the largest coherent slice that still fits the actual context budget of the loop you plan to run.
498
+
499
+ ### Lessons from prior Ralph-loop reviews
500
+
501
+ The `tenant-scoped-content-versioning` example and subsequent reviews produced the concrete rules in this guide. Key findings:
502
+
503
+ 1. **Medium atomic tasks beat both vague tasks and micro-tasks.** The worst plans combined tiny mechanical subtasks with broad ambiguous ones. Better: merge obvious same-file mechanical work, split only tasks that still hide policy or control-flow decisions.
504
+
505
+ 2. **Human handoffs must be documented but not executed by the loop.** Stage rollout validation, signoff, and production-only checks belong in a dedicated handoff section, outside the checkbox path the loop consumes.
506
+
507
+ 3. **Unresolved policy questions become loop churn.** Phrases like "reuse the current staged version for the same release cycle," "validate critical failures," or "may be shared or tenant-specific" are acceptable in human planning but bad for a Ralph loop. A fresh-session agent will treat them as missing decisions and thrash.
508
+
509
+ 4. **Every wide task needs explicit "done when" signals.** Verbs like `ensure`, `validate`, `keep`, or `support` are too soft on their own.
510
+
511
+ 5. **Full OpenSpec context is better than raw task-file mode.** Repo guidance favors `./scripts/ralph-run.sh tasks <change>` over raw `tasks.md` mode because `opsx-apply` provides a manifest (`## OpenSpec Artifacts`) listing artifact paths so the agent can read proposal, design, and specs as needed. A task list can be shorter when the design/specs fully resolve tricky decisions, but only if the loop actually references those artifacts each iteration.
512
+
513
+ 6. **"Done when" gates are hard stops, not soft guidelines.** The most common single-task quality failure is a loop marking a task complete after a `Done when` check failed, with a rationalization note. The gate is self-authorizing; the loop decides the gate does not apply, bypasses it, and moves on, recording a completion claim the stated verifier never confirmed.
514
+
515
+ 7. **"Pre-existing" is a claim that requires a before-baseline, not a judgment call.** In the absence of a before-baseline, any test failure during a task could equally be a regression. Baselines must exist in writing before code changes land.
516
+
517
+ 8. **Permissive reasoning for a known-broken validator bleeds to all validators.** A loop told "document tsc failures and continue" will generalize that to `npm test`, browser tests, or any other gate. Fix: name both known-broken and required-clean validators explicitly.
518
+
519
+ 9. **Establish baselines before the first code-writing task in a chain.** Otherwise the loop has no clean before-state and cannot reliably distinguish its own regressions from pre-existing issues.
520
+
521
+ 10. **Large binary assets in tool responses cause context overflow and loop restarts.** Screenshots read back into context can exceed provider limits, force compaction, and discard intermediate state — including prior task completion status.
522
+
523
+ ### What "Ralph-friendly" means in practice
524
+
525
+ A Ralph-friendly spec or task set has these properties:
526
+
527
+ 1. One loop item equals one coherent slice of behavior.
528
+ 2. "Done" is frozen up front and not negotiated mid-run.
529
+ 3. Verification is explicit and runnable.
530
+ 4. The agent is not asked to choose product or rollout policy.
531
+ 5. Human-only checks are durable but excluded from autonomous execution.
532
+ 6. Repeated failure patterns are corrected by editing the artifact, not by hoping the next session "remembers."
533
+ 7. The loop can stop honestly with a blocker rather than improvise.
534
+
535
+ ### Bottom line
536
+
537
+ The best Ralph-friendly OpenSpec proposal is not the most detailed artifact in the abstract. It is the artifact set that leaves the loop with the fewest judgment calls.
538
+
539
+ If a fresh-session agent can read the artifacts, pick one coherent increment, verify it objectively, stop honestly on blockers, and leave the repo in a clean state — the proposal is Ralph-friendly.
540
+
541
+ ---
542
+
543
+ ## Source notes
544
+
545
+ Durable repo-local sources used:
546
+
547
+ - `scripts/RALPHY-OPENSPEC-RUNNING.md`
548
+ - `scripts/templates/features-template.json`
549
+ - `scripts/templates/prd-template.md`
550
+ - `scripts/ralph-run.sh`
551
+ - `hidden/RALPH-WIGGUM-OPENSPEC.md`
552
+ - `hidden/RALPH-WIGGUM-CURSOR.md`
553
+
554
+ Prior internal Ralph-loop review conversations also informed this note.
555
+
556
+ External references consulted:
557
+
558
+ - Anthropic, "Effective harnesses for long-running agents" — `https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents`
559
+ - Anthropic, "Harness design for long-running application development" — `https://www.anthropic.com/engineering/harness-design-long-running-apps/`
560
+ - Claude docs, "Claude 4 best practices" → "Multi-context window workflows" — `https://docs.claude.com/en/docs/build-with-claude/prompt-engineering/claude-4-best-practices#multi-context-window-workflows`
561
+ - Geoffrey Huntley, "Ralph Wiggum as a software engineer" — `https://ghuntley.com/ralph/`
562
+ - Geoffrey Huntley, "everything is a ralph loop" — `https://ghuntley.com/loop/`
563
+ - Ralph TUI docs: `create-prd` and `convert` — `https://ralph-tui.com/docs/cli/create-prd`, `https://ralph-tui.com/docs/cli/convert`
564
+
package/QUICKSTART.md CHANGED
@@ -53,16 +53,19 @@ git init
53
53
  # 2. Initialize OpenSpec
54
54
  openspec init
55
55
 
56
- # 3. Create a new change
56
+ # 3. Ralphify your project (enables Ralph-friendly artifact generation)
57
+ ralph-run init
58
+
59
+ # 4. Create a new change
57
60
  openspec new change add-hello-world
58
61
 
59
- # 4. Review and complete the OpenSpec artifacts
62
+ # 5. Review and complete the OpenSpec artifacts
60
63
  # (openspec/changes/add-hello-world/proposal.md)
61
64
  # (openspec/changes/add-hello-world/design.md)
62
65
  # (openspec/changes/add-hello-world/specs/*/spec.md)
63
66
  # (openspec/changes/add-hello-world/tasks.md)
64
67
 
65
- # 5. Run the ralph loop (executes tasks with opencode)
68
+ # 6. Run the ralph loop (executes tasks with opencode)
66
69
  ralph-run --change add-hello-world
67
70
  ```
68
71
 
@@ -145,6 +148,7 @@ openspec schemas # List available workflow schemas
145
148
  ### Ralph Loop Commands
146
149
 
147
150
  ```bash
151
+ ralph-run init # Configure project for Ralph-friendly artifact generation
148
152
  ralph-run # Auto-detect most recent change and run
149
153
  ralph-run --change <name> # Run for specific change
150
154
  ralph-run --verbose # Run with debug output
@@ -165,31 +169,34 @@ cd my-web-app
165
169
  git init
166
170
  openspec init
167
171
 
168
- # 2. Create a feature
172
+ # 2. Ralphify your project
173
+ ralph-run init
174
+
175
+ # 3. Create a feature
169
176
  openspec new change user-authentication
170
177
 
171
- # 3. Go through the workflow
178
+ # 4. Go through the workflow
172
179
  # - Create proposal: Why add auth?
173
180
  # - Create specs: Login flow, password reset, OAuth
174
181
  # - Create design: Use JWT, store hashed passwords
175
182
  # - Create tasks: 15 checkboxes for implementation
176
183
 
177
- # 4. Execute the implementation
184
+ # 5. Execute the implementation
178
185
  ralph-run --change user-authentication
179
186
 
180
- # 5. Watch the magic happen!
187
+ # 6. Watch the magic happen!
181
188
  # [INFO] Found 15 tasks to execute
182
189
  # [INFO] Executing task 1/15: Create User model
183
190
  # [INFO] Executing task 2/15: Implement password hashing
184
191
  # ...
185
192
 
186
- # 6. Add context mid-run if needed (from another terminal)
193
+ # 7. Add context mid-run if needed (from another terminal)
187
194
  ralph-run --add-context "Prefer bcrypt over argon2 for password hashing"
188
195
 
189
- # 7. Check status
196
+ # 8. Check status
190
197
  ralph-run --status
191
198
 
192
- # 8. Verify the implementation
199
+ # 9. Verify the implementation
193
200
  git log --oneline # 15 commits, one per task
194
201
  git diff HEAD~15 # See full implementation
195
202
  ```
@@ -412,6 +419,21 @@ nvm use 24
412
419
  # Or install from https://nodejs.org
413
420
  ```
414
421
 
422
+ ### "Project not ralphified"
423
+
424
+ **Problem:** Running `ralph-run --change <name>` shows a warning that the project is not ralphified, or artifacts are missing Ralph-friendly structure.
425
+
426
+ **Solution:**
427
+ ```bash
428
+ # Run ralphify init to configure the project (run once after openspec init)
429
+ ralph-run init
430
+
431
+ # Verify ralphification succeeded
432
+ ralph-run --status
433
+ ```
434
+
435
+ This sets up Ralph-friendly rules in `openspec/config.yaml` and `AGENTS.md`. Run it once per project after `openspec init`.
436
+
415
437
  ### "npm: command not found"
416
438
 
417
439
  **Problem:** npm is not installed or not in PATH