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/CHANGELOG.md +90 -0
- package/README.md +67 -17
- package/agents/quest-executor.md +2 -2
- package/hooks/hooks.json +40 -5
- package/hooks/subagent-stop.mjs +140 -10
- package/lib/cli.mjs +98 -1
- package/lib/codex-native.mjs +246 -0
- package/lib/config.mjs +1 -1
- package/lib/contract.mjs +22 -2
- package/lib/help.mjs +23 -4
- package/lib/runner.mjs +59 -3
- package/lib/store-github.mjs +34 -2
- package/lib/store-local.mjs +32 -2
- package/lib/store.mjs +2 -0
- package/lib/workers.mjs +26 -12
- package/package.json +3 -3
- package/skills/orchestrate/SKILL.md +64 -11
- package/skills/orchestrate/agents/openai.yaml +1 -1
- package/skills/plan/SKILL.md +11 -2
- package/skills/plan/agents/openai.yaml +1 -1
- package/skills/protocol/SKILL.md +2 -2
- package/skills/protocol/agents/openai.yaml +1 -1
- package/skills/protocol/references/contract-spec.md +14 -5
- package/skills/protocol/references/protocol.md +12 -4
- package/skills/retro/SKILL.md +2 -2
- package/skills/retro/agents/openai.yaml +1 -1
- package/skills/setup/SKILL.md +56 -0
- package/skills/setup/agents/openai.yaml +7 -0
- package/skills/work/SKILL.md +3 -3
- package/skills/work/agents/openai.yaml +1 -1
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
|
|
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
|
|
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
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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", "
|
|
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
|
|
343
|
-
|
|
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.
|
|
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": "
|
|
9
|
-
"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
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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 →
|
|
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
|
|
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
|
-
|
|
108
|
+
every quest in this wave shows complete or blocked in `quest list --json` output
|
|
58
109
|
```
|
|
59
110
|
|
|
60
|
-
|
|
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?
|
|
74
|
-
|
|
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."
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -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
|
|
69
|
-
|
|
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`."
|
package/skills/protocol/SKILL.md
CHANGED
|
@@ -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
|
|
39
|
-
|
|
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). `
|
|
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
|
|
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
|
|
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.
|
package/skills/retro/SKILL.md
CHANGED
|
@@ -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
|
|
50
|
-
Start the next wave with
|
|
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
|
+
```
|
package/skills/work/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
|
73
|
-
mention it so
|
|
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."
|