Skip to content

Fix the runner's post-merge review findings - #210

Merged
kixelated merged 2 commits into
mainfrom
quest/m0/kix/runner-hardening
Oct 24, 2026
Merged

kixelated merged 2 commits into
mainfrom
quest/m0/kix/runner-hardening

Conversation

@kixelated

@kixelated kixelated commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m0/kix/runner-hardening.md. It fixes the two findings from Codex's post-merge review of kixelated/quest#188.

Summary

  • One runner per home (P1). quest runner now holds its home through RunnerHome.hold() and releases it on exit. A second runner on the same home refuses with another quest runner is running in <home> (process N on host); stop it first (exit 1).
    • Each runner writes its own record under <home>/running/ before it looks for other records. If two runners start at the same moment, at least one sees the other and refuses, so the two never run together. This is the same pattern quest agent uses to claim a worktree in src/cli/agent.ts.
    • A record whose process has exited (from a crash or kill -9) is removed and ignored. Liveness comes from alive() in src/cli/supervise.ts. On Linux that function compares the process start time, so a reused PID does not count as the old holder. This works on Linux and macOS.
    • A runner whose connection kix replaces now settles done only after its agents have exited, as shutdown() already did. Before this, it could give up the home while its agents were still stopping inside job checkouts.
  • Page review threads (P2). The context read in cloudflare/src/github/service.ts follows reviewThreads pageInfo cursors until it has read every thread, and only then filters for unresolved ones. Pages after the first fetch only reviewThreads. A cursor that is missing or repeats raises an error instead of looping forever.
  • README: notes that one quest runner runs in a home at a time.
  • Removes the quest file and its entry in the kix epic.

Tests

  • test/runner.test.ts:
    • a second hold on a held home is refused, both within one process and across processes
    • the home can be taken again after its holder is killed with SIGKILL
    • a replaced runner settles only after its agent exits (this test fails without the runner.ts change)
  • cloudflare/test/publish.test.ts: a pull request with 250 review threads returns the unresolved threads from all three pages, with cursors null, "100", "200".
  • just check and just test pass locally.

Choices made without asking

  • Record files instead of flock. Bun and Node have no built-in flock. Calling it through bun:ffi would not run under vitest on Node. Instead this reuses the record-then-scan pattern the repo already has. The cost: if two runners start at the very same moment, both may refuse; they never both run.
  • Records from another host count as alive. This applies when a home sits on a shared filesystem, and it matches alive(). The cost is a refusal until someone removes the stale record by hand.
  • Exit code 1 for a busy home, not 2: a busy home is not a usage error.

Suggested follow-ups

  • context still caps each thread at its first 50 comments, and also reads only the last 100 PR comments, the last 50 reviews, and 100 check contexts. A busy PR can lose data at any of these caps, just as it did with threads.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 2 commits October 23, 2026 23:03
…text

A runner records itself in <home>/running before looking for others, so a
second runner on the same home refuses; a crashed holder's record is
ignored and removed. A replaced runner now settles only once its agents
exit, so it never lets go of the home while they still stop.

The context read follows reviewThreads cursors until every thread is
examined, so a busy pull request's newer unresolved threads are kept.

Finishes quest/m0/kix/runner-hardening.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review October 24, 2026 06:18
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T06:18:59.775745Z c027ac0 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-24T06:21:22.961492Z c027ac0 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Landing c027ac0cb00d4312537e2417fa5fe29f4a216921 as a squash merge.

  • Changes: quest runner holds its home via record files under <home>/running/ (a second runner refuses with exit 1, dead records are ignored), a replaced runner settles only after its agents exit, and the context read pages reviewThreads until exhausted.
  • Checks: all 17 checks pass; Codex reviewed this head with no findings; quest check --base origin/main passes on the head.
  • Decisions: the choices listed in the PR body (record files over flock, cross-host records count as alive, exit 1 for a busy home) stand as made.
  • Follow-up: context still caps comments, reviews, and check contexts per PR; worth a /quest-plan.

(Written by Claude Opus 5.5)

@kixelated
kixelated merged commit 8fa8511 into main Oct 24, 2026
17 checks passed
@kixelated
kixelated deleted the quest/m0/kix/runner-hardening branch October 24, 2026 15:03
kixelated added a commit that referenced this pull request Oct 24, 2026
Keep both the plan context test and #210's busy review threads test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 24, 2026
Resolve the publish test conflict with #210's review-thread paging: keep the
seeded GitHub fake, teach it to page review threads 100 at a time, and port the
busy pull request test onto it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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