Skip to content

F: wire the planning provider into the server (suggestions through lane D) #117

Closed

Description

@mchwang

Problem

PR #45 adds runner/planning-provider.ts, E2's provider over lane D. Nothing in production uses it. web/server.ts accepts an optional PlanningDeps, but web/cli.ts never passes one. So POST /api/plan/suggestions always answers "Planning agent not available yet." A real review cannot ask Claude for plan suggestions.

Goal

A production review with a GitHub issue can ask Claude for plan suggestions. Each request runs in lane D's planning container, with the same isolation, cleanup and recovery guarantees Ask has.

Work

  1. Planning worker. Run the provider in a worker thread, as Ask does (runner/question-worker.ts, runner/question-agent.ts). Lane D's image build, clone and storage calls are synchronous. On the request thread they would block the server and E3's timer.
    • The worker's TMPDIR is a planning root recorded in a durable ledger beside the database. This covers the input and auth staging that lane D leaves when it gives up on cleanup.
    • The worker has its own owner token per database, separate from Ask's, so neither feature's recovery removes the other's containers.
    • Owner-scoped recovery runs before the first request, a final release runs at shutdown, and a crashed worker keeps planning off until restart.
  2. Shared container runner. createPlanningProvider and askInContainer are near copies. Extract one read-only runner, parameterized by phase, schema, IDs, refusals and leftovers. Ask's behavior must not change.
  3. Timeout. E3's default suggestion timeout is 120 s. The provider's budget is 10 minutes, and lane D's cap is 10 minutes. Make them agree.
  4. Inputs. PlanningDeps.describe() is synchronous, but the issue title, body and comments come from GitHub. Fetch them before the request starts, with a bound. Approved lessons are empty until L1–L4 exist.
  5. Wiring. web/cli.ts passes PlanningDeps for a non-demo review with a github block. Codex is refused (D: decide how Codex reads code in review, execute and fix (shell is off in every phase) #93). Demos never plan.

Out of scope

  • Drafting a revision-one plan from an issue. There is no endpoint for it yet; file separately.
  • UI changes beyond what the existing suggestion flow already shows.

Acceptance

  • With a GitHub issue configured, POST /api/plan/suggestions runs Claude in lane D and publishes cards, in a test with lane D stand-ins.
  • A real-Docker test (agent-isolation workflow) runs one planning request end to end, or this is deferred with a reason.
  • Restart after a crash removes planning's leftovers by its owner, and never touches Ask's.
  • Ask's existing tests pass unchanged.

Follows #45. Related: #28 (lane D), #29 (lane E).

🤖 Generated with Claude Code

Activity

  1. mchwang commented on Oct 4, 2026

    @mchwang
    ContributorAuthor

    Decisions (2026-10-03):

    1. Timeout: one 10-minute budget. E3's suggestion timer and the provider share lane D's cap, and setup counts against it.
    2. Shared container runner is part 1. Extract one read-only runner from askInContainer and the planning provider, with Ask unchanged. Part 2 adds the planning worker and wiring on top of it.
    3. Gate: planning is enabled for any non-demo review with a github block. It needs no runner block.
    4. Vendor: planning follows Ask's provider setting, and Codex is refused (D: decide how Codex reads code in review, execute and fix (shell is off in every phase) #93).

    🤖 Generated with Claude Code

  2. mchwang commented on Oct 4, 2026

    @mchwang
    ContributorAuthor

    Done in two parts, both squash-merged after test and real-docker passed:

    Follow-ups noted in #120: switch the prompt's base ref to github.baseBranch once #110 lands; add a test for the CLI wiring.

    🤖 Generated with Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions