Skip to content

feat(hold): one quest:active hold; quest merge takes no label - #326

Open
kixelated wants to merge 3 commits into
mainfrom
remove-merge-label
Open

kixelated wants to merge 3 commits into
mainfrom
remove-merge-label

Conversation

@kixelated

@kixelated kixelated commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Change

The user decided on 2026-10-31 to delete quest:merge, then also quest:ready. That leaves one hold label, quest:active, which means an agent is working on the PR.

  • quest iterate <pr> [token] adds quest:active and prints the hold token. Given a token, it keeps that hold.
  • quest ready <pr> <token> marks the PR ready for review and drops its ## Decisions needed section. It keeps the hold and adds no label. --done is gone, and so is the token-less take.
  • quest merge <pr> --land <sha> adds no label. It only enables pinned auto-merge: a quest land pin, a merge queue, or a direct merge, the same paths as before. It refuses while any session holds the PR. It now rereads the PR right before landing and refuses if the PR was retargeted, the head moved, or someone took it. It takes no token and no longer runs without --land.
  • quest release is unchanged.
  • quest land no longer touches labels. Ejection only disables auto-merge. The fixer's requeue only re-enables pinned auto-merge. The fallback close only closes the PR and comments.
  • Updated quest status (through the shared reader), the CLI help, README, CONTRIBUTING, and the merge, review, and iterate skills. Also updated two quest files that described the label.

Compatibility with older quest versions

All of this lives in one place, LEGACY_IGNORED in src/core/hold.ts. It can be deleted once the repos that pin quest have upgraded.

  • Repos that pin older quest binaries still add quest:iterate and quest:ready. Both still count as holds, as every quest:* label does. A refusal names them, and their token releases them. Passing such a token to quest iterate swaps the label for quest:active.
  • A quest:merge label still on an open PR is ignored, by the CLI, by quest status, and by kix. It doesn't count as a hold and is never removed. One case to know: an old-binary session that is still inside its own quest merge take no longer blocks new-binary sessions.
  • Older binaries treat quest:active and quest:kix as holds, since they match on the quest:* prefix.

kix

kix's merge job now holds its PR with its own label, quest:kix (KIX_LABEL in cloudflare/src/github/service.ts). The label is still quest:*, so local sessions respect it, and kix respects their quest:active. kix drops its spent-merge-hold cleanup: the dequeue webhook and the 5-minute sweep already release its label once a landing ends unmerged. The runner prompt names quest:kix as the job's own hold.

Decisions

  • kix gets quest:kix instead of keeping the quest:merge string. Keeping quest:merge would conflict with ignoring that label everywhere: local sessions would stop respecting kix holds. Recommendation: keep quest:kix.
  • No migration for kix merge jobs in flight at deploy time. Codex flagged this in round 1 and I left it as is. Such a job's later deliver is refused, which pauses it on a decision, and its old quest:merge label is left behind, ignored. Merge jobs are short-lived. Handling it would spread legacy code into kix's hold, release, and land paths. Recommendation: accept it, and re-pick any affected job.
  • quest merge takes no token. A session that holds the PR releases it first. /quest-review now says to release before going on to /quest-merge. Recommendation: keep; the merge skill runs inline, never pushes, and needs no hold.
  • quest ready requires the token and drops --done. Its old token-less form was a take, which quest iterate now does. Recommendation: keep.

Suggested follow-up

  • Delete the legacy handling (LEGACY_IGNORED in src/core/hold.ts and its notes in README and quest iterate --help) once quest, moq, moq.pro, rind, and rust2 have moved past this change. At that point, decide whether hold labels should become the exact set quest:active and quest:kix rather than any quest:* label.

Merge with main

Merged origin/main at a27cacd (no rebase). Main's new quest land work still wrote quest:merge. The daemon only ever wrote the label and never read it: it finds queued PRs by their pinned auto-merge. So the resolution carries this PR's decision through with no new design:

  • The fixer's collection no longer re-adds the label on a requeue, and a handback no longer removes it. Parking never touched it.
  • Updated the quest land serve help, the README's land section, and the land-park.ts comment, so they no longer describe the label.
  • In test/land.test.ts, the parked, ejected, and handback tests no longer assert on the label. The requeue tests now assert that the fixer adds none.

Deployed host daemons need no migration: a quest:merge left on a queued PR is ignored (LEGACY_IGNORED). The daemon stops removing it once the hosts upgrade, so stale labels may stay on such PRs. They hold nothing.

Checks

  • just check: passed
  • just test (run with CLAUDE_CONFIG_DIR unset): passed, 765 CLI tests (2 skipped) and 426 Worker tests

Review

  • Reviewer: Codex (gpt-6.1-sol, medium) via quest review --base origin/main
  • Earlier session, before the merge: round 1 at 14c50e6 (2 findings: in-flight kix merge jobs, refuted; base retarget, fixed in 54c112d), round 2 at 54c112d (0 findings).
  • New session after the hand-resolved merge, round 1 at 3f9fbb37abae5a10878f18a8c4423869d8aa7844, 1 finding:
    • Medium: cloudflare/src/github/service.ts:1743, kix merge jobs in flight at deploy time are refused because their stored hold names quest:merge. Refuted: this is the recorded decision "No migration for kix merge jobs in flight at deploy time" above, which the maintainer accepted by picking /quest-merge on 2026-11-01. Such a job pauses on a decision and can be re-picked.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 2 commits October 31, 2026 09:47
Delete quest:merge and quest:ready. A session working on a PR holds the
single quest:active label: quest iterate takes it, quest ready keeps it
while marking the PR ready, and quest release hands it back. quest merge
--land only enables pinned auto-merge, refusing while any session holds
the PR; the auto-merge is the queue signal. quest land's ejection, fixer
requeue, and fallback close no longer touch labels.

Older quest versions' quest:iterate and quest:ready still hold a PR like
any quest:* label, and their quest:merge is ignored, in one place in
src/core/hold.ts. kix's merge job holds its PR with its own quest:kix
label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 51 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 63f0057e-2d06-4408-a406-67d5db90ea92
Commits

Reviewing files that changed from the base of the PR and between a27cacd and 3f9fbb3.

Files selected for processing: 31
  • CONTRIBUTING.md
  • README.md
  • assets/skills/iterate.md
  • assets/skills/merge.md
  • assets/skills/review.md
  • cloudflare/GITHUB.md
  • cloudflare/README.md
  • cloudflare/src/github/service.ts
  • cloudflare/src/github/state.ts
  • cloudflare/src/inbox/model.ts
  • cloudflare/src/jobs/landing.ts
  • cloudflare/src/jobs/routes.ts
  • cloudflare/src/jobs/store.ts
  • cloudflare/test/inbox.test.ts
  • cloudflare/test/jobs.test.ts
  • cloudflare/test/publish.test.ts
  • quest/m0/helpers/merge-land.md
  • quest/m0/host-land/README.md
  • src/cli/hold.ts
  • src/cli/land-fixer.ts
  • src/cli/land-head.ts
  • src/cli/land-park.ts
  • src/cli/land.ts
  • src/cli/main.ts
  • src/core/hold.ts
  • src/core/index.ts
  • src/runner/prompt.ts
  • test/hold-policy.test.ts
  • test/hold.test.ts
  • test/land.test.ts
  • test/status.test.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Carry the PR's decision through main's new land code: the fixer's requeue no
longer re-adds `quest:merge`, its handback and ejection no longer remove it, and
the docs and tests stop describing the label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant