quest-loop 0.1.0 → 0.3.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/lib/workers.mjs CHANGED
@@ -46,7 +46,7 @@ function workInstructions(id) {
46
46
  return (
47
47
  "Work quest " +
48
48
  id +
49
- " per the /quest:work skill. The quest store is in this directory. " +
49
+ " per the $quest:work skill. The quest store is in this directory. " +
50
50
  "End every iteration by running quest show " +
51
51
  id +
52
52
  "."
@@ -242,20 +242,28 @@ const CODEX_CREATE_GOAL_CORRECTION = (id) =>
242
242
  "You did not invoke the create_goal tool — you narrated it instead. Call the create_goal tool now " +
243
243
  "(a real tool call, not prose) with the stopping condition, verify with get_goal, then continue working quest " +
244
244
  id +
245
- " per /quest:work.";
245
+ " per $quest:work.";
246
246
 
247
247
  export const codex = {
248
248
  name: "codex",
249
249
 
250
250
  buildInvocation(questRecord, config, opts) {
251
251
  const { id } = opts;
252
- const prompt =
253
- "First step: Create a goal for this thread using the create_goal tool (not as prose) with this exact " +
254
- "stopping condition: " +
255
- stoppingCondition(id, opts.runStartIso) +
256
- '. Verify with get_goal. Only call update_goal(status="complete") AFTER `quest checkpoint` succeeded.' +
257
- "\n" +
258
- workInstructions(id);
252
+ const goalMode = opts.codexGoalMode ?? "auto";
253
+ const condition = stoppingCondition(id, opts.runStartIso);
254
+ // Each mode gets its own complete, self-terminating instruction. Every mode —
255
+ // including `off` — names the `quest checkpoint` command, which is the sole
256
+ // machine-verifiable stop signal a headless worker must emit.
257
+ const goalLine =
258
+ goalMode === "off"
259
+ ? `Do not rely on goal tools. Treat this as the run contract — stopping condition: ${condition}. ` +
260
+ 'Record progress with `quest checkpoint`; only report the quest complete AFTER `quest checkpoint` succeeded.'
261
+ : goalMode === "require"
262
+ ? `First step: Create a goal for this thread using the create_goal tool (not as prose) with this exact stopping condition: ${condition}. ` +
263
+ 'Verify with get_goal. Only call update_goal(status="complete") AFTER `quest checkpoint` succeeded.'
264
+ : `If goal tools are available in this exec surface, create a goal for this thread using the create_goal tool with this exact stopping condition: ${condition}. ` +
265
+ 'If you created a goal, verify with get_goal. Only call update_goal(status="complete") AFTER `quest checkpoint` succeeded.';
266
+ const prompt = goalLine + "\n" + workInstructions(id);
259
267
  const artifactsFile = codexArtifactsFile();
260
268
  const args = [
261
269
  "exec",
@@ -287,7 +295,7 @@ export const codex = {
287
295
  const args = ["exec", "resume"];
288
296
  if (sessionArg === "--last") args.push("--last");
289
297
  else args.push(sessionArg);
290
- args.push(text, "--json", "-C", opts.cwd, "--skip-git-repo-check", "-o", artifactsFile, "--output-schema", opts.schemaPath);
298
+ args.push(text, "--json", "--skip-git-repo-check", "-o", artifactsFile, "--output-schema", opts.schemaPath);
291
299
  if (opts.effort) args.push("-c", `model_reasoning_effort=${opts.effort}`);
292
300
  const basePath = opts.env?.PATH ?? "";
293
301
  const env = { PATH: `${join(opts.pluginRoot, "bin")}:${basePath}` };
@@ -339,8 +347,10 @@ export const codex = {
339
347
  const first = await runSegment(this.buildInvocation(questRecord, config, opts));
340
348
  let sawGoal = codexUsedCreateGoal(first.events || []);
341
349
 
342
- // Corrective resume: create_goal was narrated, not invoked.
343
- if (!sawGoal) {
350
+ // Corrective resume only when the caller explicitly requires goal tools.
351
+ // In auto/off modes the documented Codex exec JSONL + output-schema path is
352
+ // the contract; goal tools are useful but not assumed available.
353
+ if (!sawGoal && opts.codexGoalMode === "require") {
344
354
  correctiveResume = true;
345
355
  resumes += 1;
346
356
  const corr = this.buildResume(questRecord, config, opts, "--last", CODEX_CREATE_GOAL_CORRECTION(opts.id));
@@ -348,6 +358,10 @@ export const codex = {
348
358
  if (codexUsedCreateGoal(cres.events || [])) sawGoal = true;
349
359
  }
350
360
 
361
+ if (opts.codexGoalMode === "require" && !sawGoal) {
362
+ return { session_id: sessionId, cost_usd: cost, tokens, invocations, sawGoal, correctiveResume, resumes, goalToolMissingRequired: true };
363
+ }
364
+
351
365
  // Same-session continuation while the stopping condition is unmet.
352
366
  while (resumes < CODEX_MAX_RESUMES) {
353
367
  const state = await ctx.readState();
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "quest-loop",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Goal-loop engineering for coding agents: quest contracts, iterative execution with evidence checkpoints, Claude + Codex workers. Ships the `quest` store CLI and the `quest-run` headless runner.",
5
5
  "type": "module",
6
6
  "engines": { "node": ">=20" },
7
7
  "bin": {
8
- "quest": "./bin/quest",
9
- "quest-run": "./bin/quest-run"
8
+ "quest": "bin/quest",
9
+ "quest-run": "bin/quest-run"
10
10
  },
11
11
  "files": [
12
12
  "bin/",
@@ -22,11 +22,14 @@ trails, and escalations only where a human ruling is genuinely needed.
22
22
  quest runs --active # headless runners that outlived prior sessions
23
23
  ```
24
24
  2. **Dispatch** each ready quest per its record:
25
- - `worker: claude` spawn the `quest-executor` subagent with the record's
26
- `model`/`effort` as the dispatch override; prompt = "Work quest <id> per
27
- /quest:work."
28
- - `worker: codex`, parallel batches, or anything long-running → run
29
- `quest-run <id>` in **background Bash** and keep working; you'll be
25
+ - In Codex, prefer the native `quest-executor` custom agent for an
26
+ interactive single quest; prompt = "Work quest <id> per $quest:work." If
27
+ the agent is missing, run `quest codex install-agents --scope project` (or
28
+ `$quest:setup`) before dispatching.
29
+ - In Claude Code, spawn the `quest-executor` subagent with the record's
30
+ `model`/`effort` as the dispatch override and the same prompt.
31
+ - For headless Codex/Claude work, parallel batches, or anything long-running,
32
+ run `quest-run <id>` in **background Bash** and keep working; you'll be
30
33
  notified when it exits. Parallel file-disjoint quests:
31
34
  `quest-run --ready --parallel 3` (add `--isolate worktree` when they touch
32
35
  the same files).
@@ -42,22 +45,72 @@ trails, and escalations only where a human ruling is genuinely needed.
42
45
  Done-when items.
43
46
  - **iterate-with-feedback** — send the specific gap back (continue the
44
47
  subagent, or `quest-run <id> --continue-session`).
45
- - **split** — bigger than it looked → `/quest:plan` to decompose; cancel or
48
+ - **split** — bigger than it looked → `$quest:plan` to decompose; cancel or
46
49
  re-parent the original honestly.
47
50
  - **escalate-to-human** — surface human-only decisions verbatim. Never
48
51
  guess a ruling the human should make.
49
52
  6. **Wave done?** When `quest list --ready` empties and nothing is in flight:
50
- run `/quest:retro` before starting the next wave.
53
+ run `$quest:retro` before starting the next wave.
54
+
55
+ ## Closing an epic
56
+
57
+ An epic is an ordinary quest that other quests name as `parent`. It is **never
58
+ dispatched to a worker**: `quest list --ready` gates it out while any child is
59
+ non-terminal, and `quest-run --ready` refuses it even once every child is
60
+ terminal (a direct `quest-run <id>` on an epic still runs, but don't — it burns
61
+ a worker on pure verification). Close it inline yourself, spending zero worker
62
+ tokens:
63
+
64
+ 1. **Verify the children are genuinely done:**
65
+ ```bash
66
+ quest list --parent <id> --json # is every child complete or cancelled?
67
+ ```
68
+ A `cancelled` child is terminal too — account for why it was dropped; it does
69
+ not block the epic and you do not wait on it.
70
+ 2. **Run the epic's own validation loop** (the integration-level check in its
71
+ record) and read each child's completion evidence — this is the real work of
72
+ closing an epic.
73
+ 3. **Record the verdict on the epic itself:**
74
+ ```bash
75
+ quest start <id>
76
+ quest checkpoint <id> --status complete \
77
+ --summary "epic closed inline — children #a #b #c verified, integration loop green" \
78
+ --validation "<epic validation loop> → <observed result>"
79
+ ```
80
+ The checkpoint must **enumerate each child and each epic Done-when item** with
81
+ its evidence — the same bar every quest meets, just discharged by you inline
82
+ rather than by a dispatched worker.
83
+
84
+ ## Reopening completed work
85
+
86
+ When review (or reality) finds a defect in a quest you already marked
87
+ **complete**, never hand-edit the status line and never redispatch a worker onto
88
+ the terminal record — `quest-run` early-exits on a complete quest and journals a
89
+ 0-session no-op. Instead reopen it:
90
+
91
+ ```bash
92
+ quest reopen <id> --reason "review found npm audit criticals after completion"
93
+ ```
94
+
95
+ This flips `complete → in_progress` and appends an audited checkpoint carrying
96
+ `reopen_reason`, so the loop keeps custody of the defect trail. Then dispatch the
97
+ quest directly by id (`quest-run <id>` or a `quest-executor` subagent) — reopened
98
+ quests are `in_progress`, so they do **not** re-appear in `quest list --ready`.
99
+ Reopening a child of a **complete** parent epic is allowed (a stderr warning, not
100
+ a block); you then rule whether the epic's completion verdict is falsified and,
101
+ if so, reopen the epic too. `cancelled` is fully terminal — file a new quest.
51
102
 
52
103
  ## Autonomous waves
53
104
 
54
105
  For an unattended wave, pin your own session to the outcome with a native goal:
55
106
 
56
107
  ```
57
- /goal every quest in this wave shows complete or blocked in `quest list --json` output
108
+ every quest in this wave shows complete or blocked in `quest list --json` output
58
109
  ```
59
110
 
60
- The harness then keeps you cycling until the wave is genuinely done.
111
+ In Codex, use the native goal tool when available; in Claude Code, use
112
+ `/goal <condition>`. The harness then keeps you cycling until the wave is
113
+ genuinely done.
61
114
 
62
115
  ## Worked example
63
116
 
@@ -70,5 +123,5 @@ quest show 12 --json # new checkpoint? quest_status? evidence?
70
123
  # reviewer on 12's diff → findings dispositioned → accept
71
124
  ```
72
125
 
73
- **Next:** contracts weak? `/quest:plan` to fix them first. Wave finished?
74
- `/quest:retro`. Vocabulary and stop rules: `/quest:protocol`.
126
+ **Next:** contracts weak? `$quest:plan` to fix them first. Wave finished?
127
+ `$quest:retro`. Vocabulary and stop rules: `$quest:protocol`.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Orchestrate Quests"
3
3
  short_description: "Dispatch workers on ready quests, verify checkpoints, rule on evidence"
4
- default_prompt: "Use $orchestrate to drive the ready quests to completion."
4
+ default_prompt: "Use $quest:orchestrate to drive the ready quests to completion."
@@ -26,6 +26,15 @@ For epics: create the parent first, then children with `--parent <id>` and
26
26
  `--depends-on` expressing the real order. `quest list --ready` becomes the
27
27
  dispatch queue — that is the whole wave mechanic.
28
28
 
29
+ Keep the **epic itself thin**. Its Done-when is **integration-level only**: it
30
+ checks that the children compose into a working whole (the end-to-end behavior,
31
+ the parity gate, the shipped docs), never a restatement of each child's
32
+ Done-when. Its milestones must **not mirror the children 1:1** — the children
33
+ *are* the decomposition, so re-listing them in the epic body earns no worker and
34
+ wastes review. Give the epic an objective, integration Done-when, and the
35
+ validation loop the orchestrator runs to close it inline (it is never
36
+ dispatched — see `$quest:orchestrate` "Closing an epic").
37
+
29
38
  ## Author the contract
30
39
 
31
40
  Every field earns its place:
@@ -65,5 +74,5 @@ quest create --title "Add dark mode to settings" \
65
74
  quest lint 12 # always, before dispatch
66
75
  ```
67
76
 
68
- **Next:** dispatch with `/quest:orchestrate` (or work it yourself via
69
- `/quest:work <id>`). Rules and vocabulary: `/quest:protocol`.
77
+ **Next:** dispatch with `$quest:orchestrate` (or work it yourself via
78
+ `$quest:work <id>`). Rules and vocabulary: `$quest:protocol`.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Plan Quests"
3
3
  short_description: "Turn an ask into evidence-checkable quest contracts"
4
- default_prompt: "Use $plan to decompose this ask into quest contracts via `quest create`."
4
+ default_prompt: "Use $quest:plan to decompose this ask into quest contracts via `quest create`."
@@ -35,5 +35,5 @@ quest protocol
35
35
  - A `complete` checkpoint cites backticked commands in `validation_summary`
36
36
  and enumerates every Done-when item as Done / Blocked / Cancelled.
37
37
 
38
- **Next:** plan with `/quest:plan`, execute with `/quest:work`, drive with
39
- `/quest:orchestrate`, improve with `/quest:retro`.
38
+ **Next:** plan with `$quest:plan`, execute with `$quest:work`, drive with
39
+ `$quest:orchestrate`, improve with `$quest:retro`.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Quest Protocol"
3
3
  short_description: "The quest loop rules, checkpoint format, and vocabulary"
4
- default_prompt: "Use $protocol to look up the exact quest loop rule before acting."
4
+ default_prompt: "Use $quest:protocol to look up the exact quest loop rule before acting."
@@ -72,7 +72,7 @@ updated: 2026-07-07T14:00:00Z
72
72
  | `effort` | no | reasoning effort passed to the worker (e.g. `xhigh`); omitted = config default |
73
73
  | `max_iterations` | yes | positive integer (counts runner **sessions**) |
74
74
  | `max_cost` | no | USD number; omitted = uncapped |
75
- | `parent` | no | quest id (epic linking; children derived by scanning) |
75
+ | `parent` | no | quest id (epic linking; children derived by scanning). A quest with children is an epic: excluded from `--ready` until every child is terminal (complete/cancelled), and closed by the orchestrator inline — never dispatched to a worker |
76
76
  | `depends_on` | no | list of quest ids (wave ordering) |
77
77
  | `created` / `updated` | yes | UTC ISO-8601 `…Z` |
78
78
 
@@ -135,7 +135,11 @@ Optional free-form note.
135
135
 
136
136
  - `quest_status` ∈ `in_progress | complete | blocked` — the only legal values.
137
137
  - `iteration` required; `pr`, `head_sha`, `failed_approaches`,
138
- `compatible_expansion` optional.
138
+ `compatible_expansion`, `reopen_reason` optional.
139
+ - `reopen_reason` is written only by `quest reopen`: it records why a `complete`
140
+ quest was legally sent back into the loop (`quest_status: in_progress`), so a
141
+ fresh session can see why a once-complete quest is in progress again. Old
142
+ parsers ignore it — `parseCheckpoints` accepts any `- key: value` line.
139
143
  - `validation_summary` required. When `quest_status: complete`, lint requires
140
144
  at least one backticked command in it (commands, not adjectives).
141
145
  - A checkpoint's `quest_status` drives the store `status` transition:
@@ -149,10 +153,15 @@ in_progress → complete (checkpoint quest_status: complete)
149
153
  in_progress → blocked (checkpoint quest_status: blocked)
150
154
  blocked → in_progress (new checkpoint quest_status: in_progress)
151
155
  todo|in_progress|blocked → cancelled (quest cancel --reason)
156
+ complete → in_progress (quest reopen --reason ONLY — never a checkpoint)
152
157
  ```
153
158
 
154
- Any other transition is illegal (exit 5). `complete` and `cancelled` are
155
- terminal.
159
+ Any other transition is illegal (exit 5). `cancelled` is fully terminal.
160
+ `complete` is terminal for **checkpoints** — a stray checkpoint can never
161
+ resurrect it — but the `quest reopen <id> --reason` verb provides the one
162
+ audited path back into the loop, flipping `complete → in_progress` and appending
163
+ a checkpoint carrying `reopen_reason`. This is a separate `assertReopen` path in
164
+ `lib/contract.mjs`, deliberately not part of the checkpoint transition table.
156
165
 
157
166
  ## GitHub backend mapping
158
167
 
@@ -161,7 +170,7 @@ terminal.
161
170
  | record | `quests/NNN-slug.md` | issue; body = same body sections |
162
171
  | orchestration metadata | frontmatter | `<!-- quest:meta -->` HTML block at top of body (same `key: value` lines) |
163
172
  | id | frontmatter `id` | issue number |
164
- | status | frontmatter | labels `quest:todo\|in-progress\|blocked\|complete\|cancelled` (+ marker label `quest`); issue state mirrored (complete → closed-completed, cancelled → closed-not-planned) |
173
+ | status | frontmatter | labels `quest:todo\|in-progress\|blocked\|complete\|cancelled` (+ marker label `quest`); issue state mirrored (complete → closed-completed, cancelled → closed-not-planned, reopen → issue reopened + label swapped back to `quest:in-progress`) |
165
174
  | priority | frontmatter | labels `quest-p0\|p1\|p2` |
166
175
  | checkpoint | appended section | issue comment, identical bytes |
167
176
  | parent/child | child `parent:` | child meta `parent:` + epic body `## Children` task list (`- [ ] #12`) |
@@ -1,7 +1,7 @@
1
1
  # The quest loop protocol
2
2
 
3
3
  This is the base protocol every quest execution follows. Local amendments (mined
4
- from retros, see `/quest:retro`) live in `.quests/amendments.md` and extend this
4
+ from retros, see `$quest:retro`) live in `.quests/amendments.md` and extend this
5
5
  document — read both. `quest protocol` prints them together.
6
6
 
7
7
  ## Vocabulary
@@ -44,7 +44,11 @@ Each iteration:
44
44
  6. **Evaluate stop conditions.**
45
45
  - `complete` — every "Done when" item is enumerated as
46
46
  **Done / Blocked / Cancelled** with its evidence, and no new TODOs or
47
- follow-up work remain inside this quest (file a new quest instead).
47
+ follow-up work remain inside this quest (file a new quest instead). If a
48
+ completed quest is later found defective, the one legal way back into the
49
+ loop is `quest reopen <id> --reason` (flips `complete → in_progress`,
50
+ appends an audited `reopen_reason` checkpoint) — never hand-edit a terminal
51
+ status line. `cancelled` stays fully terminal.
48
52
  - `blocked` — (a) two consecutive iterations failing on the same error,
49
53
  (b) a decision only a human can make, or (c) an unsatisfiable "Done when"
50
54
  — name the exact discrepancy and the corrected anchor; **never improvise
@@ -81,7 +85,7 @@ When reviewing a finished iteration or run, the orchestrator rules one of:
81
85
  - **accept** — the checkpoint's evidence actually satisfies the Done-when items
82
86
  it claims (quote the commands; never accept adjectives).
83
87
  - **iterate-with-feedback** — send the specific gap back to the executor.
84
- - **split** — the quest was bigger than it looked; decompose via `/quest:plan`.
88
+ - **split** — the quest was bigger than it looked; decompose via `$quest:plan`.
85
89
  - **escalate-to-human** — human-only decisions are surfaced verbatim, never
86
90
  guessed.
87
91
 
@@ -90,4 +94,8 @@ When reviewing a finished iteration or run, the orchestrator rules one of:
90
94
  - **Small** — one quest, worked inline in the current session.
91
95
  - **Medium** — one quest dispatched to an executor (subagent or headless run).
92
96
  - **Large** — an epic (parent quest) with child quests in dependency waves via
93
- `depends_on`; orchestrate wave by wave.
97
+ `depends_on`; orchestrate wave by wave. The epic itself is never dispatched to
98
+ a worker: it is gated out of `--ready` while any child is non-terminal, and
99
+ once the children are done the orchestrator closes it inline (verify children,
100
+ run the epic validation loop, checkpoint). Keep the epic contract
101
+ integration-level; its milestones must not mirror the children 1:1.
@@ -46,5 +46,5 @@ quest amend --text "Treat a test that fails twice in one quest as a blocker to e
46
46
  quest protocol # confirm the amendment now rides along
47
47
  ```
48
48
 
49
- **Next:** amendments feed every future `/quest:work` orient automatically.
50
- Start the next wave with `/quest:orchestrate`.
49
+ **Next:** amendments feed every future `$quest:work` orient automatically.
50
+ Start the next wave with `$quest:orchestrate`.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Quest Retro"
3
3
  short_description: "Mine finished quest traces into numbered protocol amendments"
4
- default_prompt: "Use $retro to turn this wave's traces into protocol amendments."
4
+ default_prompt: "Use $quest:retro to turn this wave's traces into protocol amendments."
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: setup
3
+ description: Use when setting up, validating, updating, or troubleshooting Quest's native Codex plugin integration.
4
+ argument-hint: "[doctor|install-agents]"
5
+ ---
6
+
7
+ # Set up Quest for Codex
8
+
9
+ Use this for Codex integration work, not for ordinary quest execution.
10
+
11
+ ## Doctor
12
+
13
+ Check the installed Codex-facing state from the actual Codex surfaces:
14
+
15
+ ```bash
16
+ quest codex doctor
17
+ ```
18
+
19
+ This verifies the Codex CLI, installed `quest@quest` plugin version, hook parser
20
+ health, neutral-directory skill roots, and whether `quest-executor` plus
21
+ `quest-reviewer` are available as native Codex custom agents.
22
+
23
+ ## Install Native Agents
24
+
25
+ Install the custom agents for this repository:
26
+
27
+ ```bash
28
+ quest codex install-agents --scope project
29
+ ```
30
+
31
+ Use user scope only when you want the agents available everywhere:
32
+
33
+ ```bash
34
+ quest codex install-agents --scope user
35
+ ```
36
+
37
+ If an existing file conflicts, inspect it first. Use `--force` only when you
38
+ intend to replace that custom agent with Quest's bundled definition.
39
+
40
+ ## Update Installed Plugin
41
+
42
+ Codex installs from marketplace snapshots. After updating or releasing Quest,
43
+ refresh and reinstall, then start a new Codex thread:
44
+
45
+ ```bash
46
+ codex plugin marketplace upgrade quest
47
+ codex plugin add quest@quest
48
+ quest codex doctor
49
+ ```
50
+
51
+ If hooks changed, review/trust the updated hook definitions in Codex when
52
+ prompted, then re-run:
53
+
54
+ ```bash
55
+ codex debug prompt-input "noop"
56
+ ```
@@ -0,0 +1,7 @@
1
+ interface:
2
+ display_name: "Quest Setup"
3
+ short_description: "Validate and install Quest's native Codex integration"
4
+ default_prompt: "Use $quest:setup to validate Quest's Codex plugin install."
5
+
6
+ policy:
7
+ allow_implicit_invocation: false
@@ -35,7 +35,7 @@ session can resume from.
35
35
  --summary "M2 done — <one line per milestone touched>" \
36
36
  --validation "\`npm test\` → 42 passed, 0 failed"
37
37
  ```
38
- 6. **Check stop conditions** (see `/quest:protocol` for the full rules):
38
+ 6. **Check stop conditions** (see `$quest:protocol` for the full rules):
39
39
  - All Done-when items hold with evidence → final checkpoint with
40
40
  `--status complete`, whose `--note` enumerates EVERY Done-when item as
41
41
  Done / Blocked / Cancelled with its evidence.
@@ -69,5 +69,5 @@ quest show 12
69
69
  ```
70
70
 
71
71
  **Next:** finished or blocked → the orchestrator (or human) rules on your
72
- checkpoint — see `/quest:orchestrate`. Learned something protocol-worthy →
73
- mention it so `/quest:retro` can turn it into an amendment.
72
+ checkpoint — see `$quest:orchestrate`. Learned something protocol-worthy →
73
+ mention it so `$quest:retro` can turn it into an amendment.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Work a Quest"
3
3
  short_description: "Execute one quest iteratively to a checkpointed stop"
4
- default_prompt: "Use $work to execute quest <id> per the quest protocol, ending in a recorded checkpoint."
4
+ default_prompt: "Use $quest:work to execute quest <id> per the quest protocol, ending in a recorded checkpoint."