ralphctl 0.7.2 → 0.8.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.
@@ -10,16 +10,11 @@ focused questions, and stop when acceptance criteria are unambiguous.
10
10
 
11
11
  ## Output target
12
12
 
13
- When approved by the user, write your final markdown body to this file:
13
+ When approved by the user, emit your final markdown body in the `refined-ticket` signal's `body`
14
+ field, written into `signals.json` per the Output contract section at the bottom of this prompt.
15
+ The harness reads the validated signal and stores its `body` on the ticket aggregate.
14
16
 
15
- ```
16
- {{OUTPUT_FILE}}
17
- ```
18
-
19
- Write a single markdown document — no JSON wrapper, no commentary, no code fence around the
20
- document body. The harness reads this file verbatim and stores it on the ticket aggregate.
21
-
22
- The expected document shape is at the bottom of this prompt under "Output format".
17
+ The expected markdown shape for the `body` is at the bottom of this prompt under "Output format".
23
18
 
24
19
  <constraints>
25
20
 
@@ -44,6 +39,16 @@ The expected document shape is at the bottom of this prompt under "Output format
44
39
 
45
40
  {{ISSUE_CONTEXT}}
46
41
 
42
+ ## Prior progress on this sprint
43
+
44
+ `progress.md` at the sprint root records every prior task-attempt on this sprint — decisions made, changes
45
+ shipped, learnings recorded. Read it before refining; honor prior decisions. The journal body as of right
46
+ now:
47
+
48
+ {{PRIOR_PROGRESS}}
49
+
50
+ If the block above is empty, no prior progress has been recorded yet on this sprint.
51
+
47
52
  ## Protocol
48
53
 
49
54
  ### Step 1 — Analyse the ticket (think first)
@@ -61,8 +66,10 @@ Then identify, in order:
61
66
 
62
67
  ### Step 2 — Interview the user
63
68
 
64
- Ask focused questions one at a time using `AskUserQuestion`, starting with the most critical
65
- gap. Work through these dimensions in priority order; skip any the ticket already nails down.
69
+ Ask focused questions one at a time as **structured multiple-choice** prompts one question
70
+ with a header, 2–4 labelled options, and a one-line description per option. Start with the most
71
+ critical gap and work through the dimensions below in priority order; skip any the ticket already
72
+ nails down.
66
73
 
67
74
  **Dimension A — Problem and scope.** What problem are we solving and for whom? What is in
68
75
  scope vs explicitly out of scope? What is deferred to future work?
@@ -85,15 +92,17 @@ limits. Phrase as observable constraints, not implementation hints.
85
92
 
86
93
  #### Asking clarifying questions
87
94
 
88
- Use `AskUserQuestion` with 2–4 options per question:
95
+ Every question is a structured multiple-choice prompt with 2–4 options. Use whichever interactive
96
+ question-asking tool your runtime exposes (Claude Code uses `AskUserQuestion`; other runtimes have
97
+ equivalents) — the shape stays the same:
89
98
 
90
99
  - First option = your recommendation (label ends with " (Recommended)").
91
100
  - Descriptions explain trade-offs or implications.
92
101
  - Ask one question at a time.
93
102
  - Labels: 1–5 words (UI rendering constraint).
94
103
  - Headers: 12 characters or fewer (UI rendering constraint).
95
- - `multiSelect: true` when choices are not mutually exclusive.
96
- - Users automatically get an "Other" option — do not add your own.
104
+ - Allow multiple selections when choices are not mutually exclusive.
105
+ - The harness automatically appends a free-form "Other" option — do not add your own.
97
106
 
98
107
  #### Example interactions
99
108
 
@@ -148,7 +157,7 @@ should we split?"
148
157
  Present the complete requirements in readable markdown. Use proper headers, bullets, and
149
158
  formatting. Make it easy to scan.
150
159
 
151
- Then ask for approval using `AskUserQuestion`:
160
+ Then ask for approval as a structured multiple-choice prompt:
152
161
 
153
162
  ```
154
163
  Question: "Does this look correct? Any changes needed?"
@@ -164,7 +173,7 @@ Iterate until approved.
164
173
 
165
174
  ### Step 5 — Pre-output quality check
166
175
 
167
- Before writing to file, verify ALL of these are true:
176
+ Before emitting the signal, verify ALL of these are true:
168
177
 
169
178
  - [ ] Problem statement is clear and agreed.
170
179
  - [ ] Every requirement has acceptance criteria covering happy path + edge / error cases.
@@ -174,16 +183,12 @@ Before writing to file, verify ALL of these are true:
174
183
  - [ ] Given/When/Then format used where it fits.
175
184
  - [ ] Multi-topic tickets use numbered headings (`# 1.`, `# 2.`, …) with `---` dividers.
176
185
 
177
- ### Step 6 — Write to file
178
-
179
- Once approved AND every checklist item is true, write the markdown body to:
180
-
181
- ```
182
- {{OUTPUT_FILE}}
183
- ```
186
+ ### Step 6 — Write `signals.json`
184
187
 
185
- Write the markdown document only no JSON wrapper, no surrounding fence, no chat commentary
186
- after the write.
188
+ Once approved AND every checklist item is true, write the validated `refined-ticket` signal into
189
+ `signals.json` as documented in the Output contract section at the bottom of this prompt. The
190
+ markdown body goes into the signal's `body` field verbatim — no JSON wrapper inside the body, no
191
+ surrounding code fence.
187
192
 
188
193
  ## Output format
189
194
 
@@ -249,6 +254,8 @@ separate them with `---`:
249
254
  ## Failure modes
250
255
 
251
256
  If, after the interview, you determine the ticket cannot be refined as stated (contradictory
252
- requirements, missing information you cannot extract from the user), still write to
253
- `{{OUTPUT_FILE}}` with whatever you have, ending with a final section explaining the gap.
254
- Do not silently invent requirements.
257
+ requirements, missing information you cannot extract from the user), still emit the
258
+ `refined-ticket` signal with whatever you have, ending the body with a final section explaining
259
+ the gap. Do not silently invent requirements.
260
+
261
+ {{OUTPUT_CONTRACT_SECTION}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ralphctl",
3
- "version": "0.7.2",
4
- "description": "Agent harness for long-running AI coding tasks — orchestrates Claude Code & GitHub Copilot across repositories",
3
+ "version": "0.8.0",
4
+ "description": "Agent harness for long-running AI coding tasks — orchestrates Claude Code, GitHub Copilot, and OpenAI Codex across repositories",
5
5
  "homepage": "https://github.com/lukas-grigis/ralphctl",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -1,14 +0,0 @@
1
- <signals>
2
-
3
- Emit exactly one of the verdict signals below at the end of your evaluation. The harness records this as the
4
- authoritative outcome and resumes the generator with the critique on failure.
5
-
6
- - `<evaluation-passed>` — Every dimension scored 4 or 5; the implementation matches the specification.
7
- - `<evaluation-failed>critique</evaluation-failed>` — At least one dimension scored 1, 2, or 3. The critique is
8
- the actionable summary the generator will see — be specific about what is wrong and what needs to change. Do
9
- not write generic praise or hedged language; the critique must point at concrete files, lines, or behaviours.
10
-
11
- Per-dimension findings belong in your markdown body above the verdict signal so a human reviewer can audit your
12
- reasoning. The signal itself is the verdict only.
13
-
14
- </signals>
@@ -1,26 +0,0 @@
1
- <signals>
2
-
3
- Use these signals to communicate task outcome to the harness. The harness parses your output for these tags; nothing
4
- else in your message is treated as a control signal.
5
-
6
- - `<task-verified>output</task-verified>` — Records the verification commands you ran and their output. Required
7
- before completion so the harness has on-disk evidence of what passed.
8
- - `<task-complete>` — Marks the task as done. Emit ONLY after `<task-verified>` and only when every declared step
9
- has been completed and every verification command passes.
10
- - `<task-blocked>reason</task-blocked>` — Marks the task as blocked. Use when you cannot proceed: missing
11
- dependency, ambiguous step, pre-existing failure, scope mismatch with the ticket. Be concrete in the reason —
12
- the harness surfaces this verbatim to the operator.
13
-
14
- Optional progress signals you may emit during long-running work:
15
-
16
- - `<progress>short summary</progress>` — A one-line status update; the harness streams these to the live UI.
17
- - `<note>text</note>` — Incidental observations that future tasks should be aware of (patterns, gotchas).
18
- - `<change>text</change>` — A concrete change you made during this task. Granular ("added X", "renamed Y to Z", "deleted Z"). The harness appends these inline to the task's section in `progress.md`.
19
- - `<learning>text</learning>` — Non-obvious project knowledge worth carrying across tasks (a hidden constraint, an undocumented convention, a gotcha you hit and resolved). The harness pins these under `## Learnings` at the top of `progress.md` so future tasks see them. Use sparingly; only the kind of insight you'd want a fresh agent to read first.
20
- - `<decision>text</decision>` — An architectural or design choice with rationale ("chose path A over B because <reason>"). Higher signal than `<learning>`. The harness pins these under `## Decisions` in `progress.md`. Use only for choices a future maintainer would want explained.
21
-
22
- Commit message — the harness owns the commit; you propose the wording (emit on every turn that produced edits):
23
-
24
- - `<commit-message><subject>type(scope): imperative present tense, ≤72 chars</subject><body>WHY this change, what was considered, follow-ups — wrap lines at 72 chars; multiple paragraphs allowed</body></commit-message>` — Proposed message for the per-task `git commit` the harness runs after this turn. **Emit this on every task that touched a file.** The subject is required and should follow a Conventional Commits shape (`feat(scope): …`, `fix(scope): …`, `refactor(scope): …`, `chore(scope): …`, `docs(scope): …`). The body is required for anything beyond a trivial rename — explain WHY the change exists, what alternatives you considered, what follow-ups remain. The diff already shows the what; your body adds the reasoning a reviewer or future maintainer can't recover from the diff alone. Emit exactly one `<commit-message>` per turn; if you emit multiple, only the last one is used. Falling through to the default `task(<id>): <name>` produces uninformative history — omit only on pure-investigation turns that wrote nothing.
25
-
26
- </signals>