Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion quest/m0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,16 @@ ownership-manifest design:
- [The land fixer resolves every mechanical failure](/quest/m0/land-fixer/README.md) - workflow pushes and the PR's own CI as context
- [Reviewer usage limits](/quest/m0/review-quota.md) - `quest review` exits distinctly on a reviewer's quota and prints the reset time
- [Drafts in quest waiting](/quest/m0/waiting-drafts.md) - `quest waiting` lists open draft PRs' `## Waiting` items beside the tree's
- [Rejected options in decision records](/quest/m0/decision-records.md) - grill and plan label rejected options so no one reads them as qualifiers
- [Decision records](/quest/m0/decision-records.md) - grill and plan label rejected options, and record a decision in the PR when the PR deletes the quest
- [Kix decision UI](/quest/m0/kix/README.md) - planning and implementation through prompts and summaries, run on the maintainer's own runners
- [Per-PR picks in /quest-complete](/quest/m0/complete-per-pr.md) - one question per PR, with no grouped or blanket option offered
- [Codex cloud off](/quest/m0/codex-cloud-off.md) - automatic Codex cloud reviews stop once no open PR relies on them
- [Bun EFAULT report](/quest/m0/bun-efault.md) - report concurrent `rmSync` `EFAULT` on Windows, and drop the workaround once Bun fixes it
- [Codex project-config skip](/quest/m0/codex-project-config.md) - once Codex keeps a supported way to skip a project's `.codex/` layer, reviews keep the user's config
- [Gate bench](/quest/m0/gate-bench.md) - measure headroom admission on an idle host
- [Agent workflow helpers](/quest/m0/helpers/README.md) - CLI commands for CI waits, PR status, claims, quest moves, and serialized merges
- [Worktree hooks here](/quest/m0/worktree-hooks.md) - `quest` reaches Claude Code's hooks and the merge driver in this repository, then `quest init` installs the hooks
- [Wrapped worktree hooks](/quest/m0/wrapped-hooks.md) - `quest init` accepts a hook that runs `… worktree hook` through a wrapper such as `nix run`
- [Remote control worktrees](/quest/m0/worktree-routes.md) - live-check `claude remote-control --spawn worktree` against the hooks, from a session spawned on claude.ai
- [Session checkouts released](/quest/m0/session-checkouts.md) - a Claude session's own checkout is released when the session ends and reclaimed on resume
- [claude rm upstream report](/quest/m0/claude-rm-upstream.md) - waiting on approval: ask Claude Code to run `WorktreeRemove` instead of advising an unlock
Expand Down
31 changes: 31 additions & 0 deletions quest/m0/complete-per-pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# [XS] /quest-complete never offers a grouped pick

## Goal

`/quest-complete` asks one question per PR and offers no option that covers
several PRs at once, such as "merge all 20 landable PRs" or "accept every
recommendation". A blanket answer that the maintainer gives on their own
still counts, as `assets/skills/complete.md` already describes.

## Plan

Decided 2026-11-03 (maintainer, /quest-complete on moq-dev/moq): "Ask per
PR. Update quest to always ask per PR." Milestone: m0, ranked right after the
Kix decision UI. moq-dev/moq runs `/quest-complete` every day, and m0's Plan
ranks the land work, then Kix, before the rest of m0.

The skill already says to ask "with one question per PR, never grouping PRs
into one question". The agent still added a grouped "merge all 20 landable
PRs" option, maybe because the next paragraph describes a blanket answer as
valid.

Implementation guidance:

- In `assets/skills/complete.md`, say that no option may name more than one
PR, so no grouped or blanket option appears, and that each question's
options are only that PR's actions.
- Reword the blanket-answer sentence so it applies only to an answer the
maintainer gives on their own, never to an option the agent offers.
- Check the other skills that ask about several PRs, such as
`assets/skills/unblock.md` and `assets/skills/afk.md`, and apply the same
rule where they put PR picks to the user.
22 changes: 21 additions & 1 deletion quest/m0/decision-records.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [XS] Recorded decisions mark the rejected options
# [XS] Decision records that last and mark the rejected options

## Goal

Expand All @@ -7,6 +7,10 @@ marked and the rejected options labelled as rejected, such as
`✅ Yes, as stated (rejected: without the overlap check; drop it)`, so no
reader takes a rejected option for a qualifier of the chosen one.

Each record also outlives its quest: a decision goes in the quest's Plan,
or in the PR body's `## Decisions` when that PR deletes the quest, since the
deletion would take the Plan's record with it.

## Plan

Decided 2026-11-02 (user, /quest-spawn follow-ups): ✅ plan as stated
Expand All @@ -18,3 +22,19 @@ Decided 2026-11-02 (user, /quest-spawn follow-ups): ✅ plan as stated
it.
- Change the recording instruction in `assets/skills/grill.md` and
`assets/skills/plan.md`. Existing records stay as written.

Decided 2026-11-03 (maintainer, /quest-complete on moq-dev/moq, planned
through moq-dev/moq's coordinator): fold where decisions are recorded into
this quest, since it changes the same recording instructions. It stays in
m0 at its rank.

- `assets/skills/plan.md` says to record each settled decision "in the
quest's Plan", and `assets/skills/unblock.md` records an answer in the
quest's Plan and then deletes a quest whose only purpose was the wait.
A PR that finishes a quest deletes its file, so a decision made in that
PR has no Plan to live in.
- Suggested wording: "record it in the quest Plan, or in the PR's Decisions
if the PR deletes the quest." Apply it in `plan.md` and `unblock.md`, and
wherever else the guide or a skill sends decisions to a quest's Plan.
`assets/skills/iterate.md` already records decisions in the PR's
description; name the same `## Decisions` section there.
2 changes: 2 additions & 0 deletions quest/m0/land-fixer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ work, done once the Required quests below have merged.

## Required

- [Leave held PRs alone](/quest/m0/land-fixer/holds.md) - the watcher never fixes, pushes to, or re-enqueues a PR another session holds
- [Run the repository's checks](/quest/m0/land-fixer/checks.md) - the fixer runs the repository's own lint, type, build, and test checks before it requeues
- [Workflow permission](/quest/m0/land-fixer/workflows-permission.md) - waits on the maintainer to grant moq-bot `workflows`, so pushes touching workflows are accepted

## Related
Expand Down
39 changes: 39 additions & 0 deletions quest/m0/land-fixer/checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# [S] The land fixer runs the repository's own checks

## Goal

Before the land fixer reports `fixed` or `requeue`, it runs the checks the
repository's own instructions name for the languages its PR and its fix
touch: lint, format, and type checks as well as build and test. On
moq-dev/moq that is `just check` and `just test`, so the JavaScript type
check runs beside the Rust build. A head the fixer re-enqueues therefore
passes what the merge queue's build will run, or goes back as a handback
quoting the failing command.

## Plan

Decided 2026-11-03 (maintainer, /quest-complete on moq-dev/moq, planned
through moq-dev/moq's coordinator): plan this follow-up. Milestone: m0,
under the land fixer epic. moq-dev/moq lands through this fixer every day,
and m0's Plan ranks the land work first.

What happened: on
[moq-dev/moq#6949](https://github.com/moq-dev/moq/pull/6949), the fixer
requeued the PR without running moq's JavaScript check, and the next build
failed on it. `assets/land-fix.md` tells the fixer to "build and test the
packages the PR and your fix touch", which it read as building and testing
only, and it skipped the check that failed.

Implementation guidance:

- Rewrite that rule in `assets/land-fix.md`: find the repository's check and
test commands in its root instructions, `CONTRIBUTING.md`, or task runner,
such as `just check` and `just test`; run them over the PR's and the fix's
changes; and name each command run in the reason. When the repository
names no check command, run each touched language's own type check and
linter beside its build and test.
- A `requeue` of an unchanged head runs the same checks, since the base may
have moved under it.
- Keep the existing rule: a check the fixer cannot run, or cannot get
passing mechanically, goes back as a handback quoting the command and its
output.
47 changes: 47 additions & 0 deletions quest/m0/land-fixer/holds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# [S] The land fixer leaves a held PR alone

## Goal

`quest land watch` neither runs the fixer on a PR another session holds, nor
pushes a fixer result to it or re-enqueues it. A hold is any hold label
`isHoldLabel` accepts (`src/core/hold.ts`), such as the `quest:active` that
`/quest-iterate` takes, or an older pin's `quest:iterate`. The watcher
checks for a hold before it starts a job and again before it pushes or
re-enqueues. A held PR gets one comment saying the watcher left it to the
session that holds it.

Non-goals: the frozen batching gate (`quest land serve`), which only
moq-dev/moq.pro still uses until it is
[retired](/quest/m0/queue-watcher/retire.md).

## Plan

Decided 2026-11-03 (maintainer, /quest-complete on moq-dev/moq, planned
through moq-dev/moq's coordinator): plan this follow-up. Milestone: m0,
under the land fixer epic. moq-dev/moq lands through this fixer every day,
and m0's Plan ranks the land work first.

What happened on
[moq-dev/moq#6949](https://github.com/moq-dev/moq/pull/6949): the
maintainer added `quest:iterate` at 2026-11-01 16:41Z for a `/quest-iterate`
session. The fixer still pushed its merge `7c10f33cbc` at 16:52Z, and moq-bot
re-armed `quest:merge` at 16:56Z, while the session was pushing its own
fixes on the same branch. The hold was lifted at 17:22Z. That was the host
gate. `quest land watch`, which replaced the gate on moq-dev/moq, has the
same gap: `src/cli/land-watch.ts` and `src/cli/land-watch-fix.ts` never read
the PR's labels for holds.

Implementation guidance:

- Read the hold labels with the snapshot the watcher already takes for each
PR the queue drops, and again right before a result is pushed or the PR is
re-enqueued, so a hold taken while the fixer runs is respected too.
- Open question for the starter: what happens to the pick of a held PR?
Recommended: the hold ends it, as a person's removal from the queue does
(`endPick`). A maintainer enqueues the PR again once its session finishes,
as `/quest-iterate`'s `/quest-merge` hand-off already does. The other
option is to wait and fix it once the hold clears, but by then the session
has usually pushed, and a push by anyone but the fixer already ends the
pick.
- Add a regression test: a PR the queue drops while it holds `quest:active`
is neither fixed nor re-enqueued.
40 changes: 40 additions & 0 deletions quest/m0/wrapped-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# [XS] quest init recognizes wrapped worktree hooks

## Goal

`quest init` treats any command hook whose arguments end in `worktree hook`
as its own, such as moq-dev/moq's
`nix run "${CLAUDE_PROJECT_DIR}#quest" -- worktree hook`, which runs the
`quest` the repository pins. It needs no configuration. In a repository with
wrapped hooks, `quest init` then succeeds without changing them, and
`quest uninstall` removes them like the plain ones.

## Plan

Decided 2026-11-03 (maintainer, moq-dev/moq, planned through moq-dev/moq's
coordinator):

- How should `quest init` recognize its hook when a repository wraps it?
- ✅ Match any command hook whose arguments end in `worktree hook`
- A configured hook command (rejected)
- No change (rejected)

Milestone: m0, ranked after [Worktree hooks here](/quest/m0/worktree-hooks.md).
m0 is adoption on moq-dev's own repositories, and moq-dev/moq hits this
today.

What happens:
[moq-dev/moq#7674](https://github.com/moq-dev/moq/pull/7674) runs moq's hooks
through its flake's pinned `quest`, so agents use the version moq pins.
`isQuestHook` (`src/core/init.ts`) matches only the exact `HOOK_COMMAND`,
`quest worktree hook`. So `quest init` counts the wrapped `WorktreeCreate`
and `WorktreeRemove` hooks as someone else's and refuses to run. The
workaround is to drop the hooks, run init, and restore them.

Implementation guidance:

- Widen `isQuestHook` to a command whose last two words are `worktree hook`.
A fresh install still writes the plain `HOOK_COMMAND`.
- `quest uninstall` (`src/cli/setup.ts`) uses the same check, so it removes
wrapped hooks too. Say so in its docs.
- Test a wrapped hook in init, re-init, and uninstall.