Skip to content

feat(kix): start ready quests on free runner slots and widen PR decisions - #564

Open
kixelated wants to merge 6 commits into
mainfrom
quest/m0/kix/execution
Open

kixelated wants to merge 6 commits into
mainfrom
quest/m0/kix/execution

Conversation

@kixelated

@kixelated kixelated commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

kix now starts ready work by itself and gives open PRs more of the /quest-complete actions, toward quest/m0/kix/execution.md. The quest file now covers only what's left: delete in the PR decision.

  • Auto-start on free slots. A maintainer can opt a project in from its inbox row ("Start ready quests on your runners"), optionally for some milestones only. When a dispatch pass leaves one of their runners with a free slot and a usable account, their hub starts the next unclaimed ready quest in quest unblocked order. Projects take turns, round-robin. Each one is an ordinary start job requested by that maintainer, created only after the same live GitHub checks as a manual start (jobSource). Two things keep failures from repeating: a quest that already had a job doesn't start again, and neither does one the maintainer skipped at its current text. The five-minute scheduled sweep wakes opted-in hubs so newly ready quests start too. The job insert itself checks that the opt-in still covers the quest's milestone, so an opt-out that commits during the GitHub read leaves no job for any dispatch to find. Projects rotate by whichever one the maintainer started work on least recently. An opt-in ends with its project membership, through a foreign key, so losing the role ends it and regaining access doesn't bring it back. The GitHub reads run outside the hub's serialized pass, so runner messages never wait on them.
  • Worth-starting check. A start job's instructions tell the agent to check first whether the quest is still worth starting. When in doubt it asks one decision: Start, Skip, Deprioritize (quest mv to a later milestone), or Delete (quest rm).
  • Held PRs name their holder. An in-progress PR row now shows who holds it. For a draft, that's its author; for a hold, it's the quest:* label.
  • Quiet-draft takeover. A starter's draft that has been quiet for a week becomes a decision. It offers "Take over and iterate" (an iterate job) or skip. A labeled hold is never offered, because its session or job releases it.
  • Mark ready. A draft handed back with ## Waiting offers "Mark ready for review". This is POST …/pulls/<n>/ready bound to the head on screen, and it's refused while a job on that PR is active.

Choices made without asking

  • Auto-start never restarts a quest that already had any job, including a cancelled or failed one. Such a quest waits in the inbox for an explicit start or retry. This follows "do not mask failures with repeated runs".
  • The quiet-draft threshold is 7 days (STALE), so a draft left over a weekend isn't offered.
  • The worth-starting check applies to every start job, manual ones included. It asks only when in doubt, so a maintainer's explicit start usually runs straight through.
  • Auto-start uses no extra approval flag. The project opt-in plus the maintainer lending their own runners is the authorization, per the epic's "Ready means eligible".
  • Delete is left for the rewritten quest. A quest PR needs a /quest-delete job, because closing it would leave its branch still claiming the quest. That's a new workflow touching the runner, publication, and landing.

Public API and wire impact

  • New routes: POST /projects/github/:owner/:repository/autostart (form enabled=1|0, milestones; JSON enabled: boolean) and POST /projects/github/:owner/:repository/pulls/:number/ready (head).
  • New D1 migration 0023_autostart.sql (table autostart, cascading from github_project_members).
  • store.createJob takes automatic and can throw NotOptedIn.
  • The runner assign message for a start job now carries non-null instructions. The protocol is unchanged.
  • Dev fake GitHub: issues and PRs take an optional updatedAt.

Validation

  • tsc --noEmit for the Worker.
  • New cloudflare/test/autostart.test.ts: ranking, milestone scope, skip, and taken rules; an opted-in runner gets its assignment; no restart after a cancel; opt-out (including during the GitHub read); project rotation; the membership cascade; role loss; mark ready at the head on screen.
  • The inbox test covers the held, quiet, and handed-back draft states. The seed covers a fresh held draft and a quiet one.
  • Full just check and just test pass (vitest 1184 passed, 5 skipped; Worker 550 passed) on the reviewed head.

Suggested follow-ups

  • None beyond the rewritten quest (delete).

Models

Implementer: Claude Code, claude-opus-5-5

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

Review

Rewritten by quest review after each round.

  • Reviewer: Codex, gpt-6.1-sol, high effort
  • Session: 01a1b8ab-8de1-75c3-a497-8a5cfb0d53cc, round 4
  • Head: 5ea467f
  • Base: origin/main at b7fb7f8
  • Score: 10/10, The latest head only merges the updated base, and static review found no new branch-specific defects or merge regressions.
  • Findings: none

Quest-Claim: dd078214e50a6435
@pullfrog

pullfrog Bot commented Nov 8, 2026

Copy link
Copy Markdown

Pullfrog  | Review this ➔

kixelated and others added 2 commits November 7, 2026 16:59
…ions

A maintainer opts a project in, optionally per milestone, and their hub
starts the next unclaimed ready quest in `quest unblocked` order whenever a
runner slot frees. Start jobs first check the quest is worth starting and ask
start, skip, deprioritize, or delete when in doubt. Held PRs name their
holder, a starter's draft quiet for a week is offered for takeover, and a
handed-back draft can be marked ready. The quest now covers only delete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Spawn and iterate work from decision prompts feat(kix): start ready quests on free runner slots and widen PR decisions Nov 8, 2026
kixelated and others added 2 commits November 7, 2026 17:07
…pt-ins with membership

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 8, 2026 01:15
@coderabbitai

coderabbitai Bot commented Nov 8, 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 3 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: 249d15e7-f749-4af5-bc62-4e0cf8e79503
Commits

Reviewing files that changed from the base of the PR and between 3b971f6 and 0b5c329.

Files selected for processing: 20

  • cloudflare/README.md
  • cloudflare/dev/github.ts
  • cloudflare/dev/seed.ts
  • cloudflare/migrations/0023_autostart.sql
  • cloudflare/src/github/service.ts
  • cloudflare/src/inbox/model.ts
  • cloudflare/src/inbox/page.tsx
  • cloudflare/src/index.tsx
  • cloudflare/src/jobs/autostart.ts
  • cloudflare/src/jobs/hub.ts
  • cloudflare/src/jobs/routes.ts
  • cloudflare/src/jobs/store.ts
  • cloudflare/src/jobs/trail.ts
  • cloudflare/test/autostart.test.ts
  • cloudflare/test/inbox.test.ts
  • cloudflare/test/jobs.test.ts
  • cloudflare/test/seed.test.ts
  • cloudflare/test/trail.test.ts
  • quest/m0/kix/README.md
  • quest/m0/kix/execution.md
  • 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

# Conflicts:
#	quest/m0/kix/README.md

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head 0b5c329 with PR base 3b971f6.

Two P2 correctness findings are recorded inline. Recommended direction: include originating jobs in the mark-ready guard, and enforce per-quest skip/history exclusions atomically when creating automatic starts.

Validation: static GitHub-only review of the 20-file diff, relevant job dispatch/publication/authorization and inbox code, and the added tests. No builds or tests were run. This is a COMMENT review, not approval.

(Written by review (OpenAI))

Comment on lines +496 to +498
// A job may still push to the pull request, so it stays as the job leaves it.
if (await store.active(c.env.DB, repo.id, `pulls/${number}`))
throw new JobError("Stop this pull request's job before marking it ready");

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Include active jobs that originally published this PR

store.active only compares jobs.target, but a start or plan job keeps its quest/issue/plan target after publishing; store.delivered records the PR number in jobs.pull without changing that target. Consequently, a running or waiting originating job that has already opened this draft is invisible to the pulls/${number} lookup, and the new endpoint can mark its PR ready even though that job can still push. Check active jobs associated through pull as well as direct PR targets, and cover a delivered draft whose originating job is still running/waiting.

(Written by review (OpenAI))

Comment on lines +175 to +180
{ ...job, repository: project.id, actor: owner, pinRunner: null, pinAccount: null, automatic: true },
Date.now(),
);
if (created.created) started++;
} catch (error) {
if (error instanceof NotMaintainer) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Recheck per-quest exclusions at automatic job insertion

The taken and skipped sets are read once before the awaited GitHub checks, while this insert only rechecks the opt-in. If the maintainer skips this quest at its current text while jobSource is reading GitHub, the skip can commit first and this code still queues and dispatches the quest. The same snapshot gap lets another in-flight pass restart a quest if a job was created and then cancelled/failed after its initial history read. Enforce the matching skip and any prior-job exclusions in the automatic insert, alongside the existing opt-in guard, so an explicit skip/cancel that commits first is respected. The opt-out-during-read test provides a useful pattern for these regressions.

(Written by review (OpenAI))

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant