Skip to content

PR Pane v1: agent-associated PR visibility + "work this PR" nudge #6

Description

@Jacksondr5

Context (read this first)

J5 Code is a fork of T3 Code being extended into a fleet-management platform: one person running many long-lived AI agents that build code, open PRs, and watch production. This issue is the first workstream of the fleet dashboard: a pane inside the app showing the pull requests the agent fleet is working on, with one action — nudging an agent about a PR.

The governing product principle — this shapes every choice below: J5 Code builds primitives that make agent workflows successful. It must never codify any particular workflow's methodology into the product. The prior art below comes from a specific three-agent PR workflow ("PR Groups") with its own playbook rules and readiness gates — that playbook is one workflow expressible on the primitives, never the product's opinion. When you face a design choice, ask "what generic capability does this need," not "how do I productize that workflow." Concretely: the prior-art dashboard computes ten workflow-specific "readiness gates" — those do not ship. The pane shows raw measured facts; workflow-defined checks become a separate, generic primitive later.

Prior art (public, study it): github.com/Jacksondr5/pr-group-dashboard — a zero-dependency Node/SQLite board built to run a real fleet of PR-working agents. Its README is a compressed field manual of operational lessons; the design principles below are distilled from it and from interviews with the agents that used it.

Principles (inherited from prior art; treat as requirements)

  1. Measured, not recalled. Every fact on screen is measured from GitHub or from platform state by code — never asserted by an agent from memory, never cached silently past its freshness.
  2. Never guess. mergeable: UNKNOWN renders as "?", a not-yet-polled row renders as "measuring…", an unreachable API renders as a loud staleness clock. A plausible fake is strictly worse than a visible gap. No state may ever look green because data was missing.
  3. Provenance is visible. Measured facts (from GitHub) and asserted facts (a human clicked "associate") are stored and rendered distinguishably. Measured tables must be safely wipe-and-rebuildable.
  4. A broken poller goes quiet, not loud-wrong. If GitHub or platform state is unreachable, keep the last data with a staleness indicator — never render an outage as "everything is fine" or "everything is dead."
  5. State is read-only; actions route through agents. The pane never acts on GitHub (no merge, no comment, no close). Its one action sends a message to an agent through the app's normal agent-messaging path, so the UI can never hold state the agents don't know about.

Scope

1. PR ↔ agent association

A PR appears on the pane when it is associated with an agent. Two association sources in v1:

  • Auto-inferred (primary): the app owns agents' worktrees and branches. When an open PR's head branch (+repo) matches a branch an agent worked on/pushed from its worktree, associate automatically. Provenance: inferred. This must be conservative — a wrong association that renders agent liveness against the wrong PR is the "plausible fake" failure principle 2 forbids. If inference is ambiguous, show unassociated rather than guessing.
  • User-asserted: the user manually associates a PR with an agent in the UI (and can remove either kind of association). Provenance: user.

Explicitly deferred: agents associating PRs themselves via a tool (raises broader agent↔platform-state design questions owned elsewhere).

2. PR state acquisition

  • GitHub only in v1, authenticated with the user's existing credentials. Keep a thin forge-abstraction seam (the prior art supports a second forge; we will again) — but build nothing Bitbucket-specific.
  • Poll, don't webhook (local desktop app; polling is self-healing). Reasonable cadence, configurable. One batched/GraphQL query per PR like the prior art; re-ask for GitHub's lazily-computed mergeability when it returns UNKNOWN.
  • Track per PR: state, draft, title, author, base/head refs, head SHA, mergeability, review decision, check-run rollup (state/total/failed/pending + failed names), unresolved review-thread count, timestamps, last-polled-at. Note: check-run completions do not bump the PR's updated_at — poll checks explicitly (prior-art lesson, learned the hard way).
  • Closed/merged PRs stay visible briefly (retention window, config), then drop.

3. The pane

  • A pane in the app's dashboard area, designed as one pane among future siblings (a fleet-attention pane will arrive later, fed by a different data source) — don't hardcode a single-pane layout.
  • One row per PR: number/title/repo; state pills (CI, mergeability, review decision, unresolved threads); the associated agent(s) with their current platform liveness chip; staleness clock when polling degrades.
  • Attention-first ordering: needs-something (failing CI, conflicting, changes-requested) above waiting (CI running, review pending) above green; stable ordering within groups — rows update in place, never jump under the cursor. Fixed-height rows; no per-second React re-renders (elapsed timers write to the DOM directly); no animated status dots. These are perf rules the codebase already follows (see AgentsPanel.tsx and AGENTS.md's performance notes — match that discipline).
  • Follow existing codebase conventions for fork-added code: new files under the j5/ surfaces (e.g. apps/server/src/j5/...), pnpm + vp toolchain, see FORK.md.

4. The nudge (v1's single action)

A "Message agent" action on each PR row: opens the normal agent-message composer prefilled with the PR reference, head SHA, and a compact snapshot of the measured state (CI/mergeability/review/threads), for the user to edit and send. It's a proof-of-concept for "work this PR" — richer verbs (e.g. spawn-an-agent-onto-a-PR) come later. The send goes through the app's existing agent messaging path; the pane adds no new channel.

Non-goals (explicit)

  • No readiness gates or any workflow-methodology logic. Raw measured facts only.
  • No agent-tool-driven association (deferred, owned elsewhere).
  • No spawn-agent-on-PR nudge (later).
  • No Bitbucket/GitLab (abstraction seam only).
  • No acting on PRs from the pane (no merge/comment/close/re-run).
  • No fleet-attention/communication pane (separate workstream; just don't preclude a sibling pane).
  • No webhooks, no public endpoints.

Acceptance criteria

  1. An agent pushes a branch from its worktree; a PR opened from that branch appears on the pane within one poll cycle, associated, provenance inferred.
  2. A PR with no inferable agent does not appear until the user associates it; the association shows provenance user.
  3. CI completion is reflected within one poll cycle even though the PR's updated_at did not change.
  4. Kill the network: rows keep last-known state with a visible staleness clock; nothing renders green-by-default; restore network → self-heals with no restart.
  5. mergeable: UNKNOWN renders as "?" and resolves after the re-ask; it never renders as mergeable.
  6. The nudge composer opens prefilled and sends through the existing agent-message path; the pane performs no GitHub write of any kind.
  7. 20+ PRs: rows update in place with stable order and fixed heights; no continuous repaint (verify against the repo's performance rules).
  8. Wipe the measured tables; they rebuild from polling with zero loss of user-asserted associations.

Negative controls required: for each "never" above (never guess, never write to GitHub, never reorder under cursor), demonstrate the check can fail — e.g., feed the UI a null mergeability and show it would catch a green rendering.

🤖 Generated with Claude Code

Activity

  1. Jacksondr5 commented on Aug 19, 2026

    @Jacksondr5
    OwnerAuthor

    Scope addition from a settled architecture ruling (X2, cross-device position paper — see docs/j5/product/cross-device/ once PR #5 merges):

    The pane must be multi-environment from day one. The client connects to multiple servers (environments) concurrently — a user may run one server on their laptop and one on a remote box. Requirements this adds:

    • The pane merges PR feeds from all connected environments (each server polls and associates its own PRs; the client aggregates), with an environment tag on each row when more than one environment is connected — same pattern the existing sidebar uses for threads.
    • Attention-first ordering applies across the merged set, not per environment.
    • An offline environment renders its last-known rows with the staleness clock (existing client cache behavior), never disappearing silently.
    • Nudges route to the agent's home environment (the association already knows it).

    This is cheap to build in now and expensive to retrofit — treat single-environment-only rendering as a review-blocking defect.

    🤖 Generated with Claude Code

  2. Jacksondr5 commented on Sep 29, 2026

    @Jacksondr5
    OwnerAuthor

    Posted by an AI agent on Jackson's behalf.

    The PR pane definition moves here (Jackson, 2026-09-29). The pane is an undeveloped idea, not a built J5 feature, so J5 doesn't claim it in its product docs; until it's built, the pull request view is upstream's. docs/j5/product/features/pr-pane.md is removed in #354, and its full text is preserved below as the design to pick up from.


    Problem

    When a fleet of agents works many pull requests at once, the person cannot tell at a glance who has reviewed what, whether a PR can be merged, whether the agents are still working it, or what they decided in response to reviews. Asking an agent means getting a recollection instead of a fact (problems: PR management is difficult; status is read, never asked). The prior-art dashboard solved this for one workflow and taught two lessons the product keeps: every fact must be measured, and a plausible fake is worse than a visible gap.

    Definition

    The PR pane shows the pull requests the fleet is working on, as measured facts, with one action: send a message to an agent about a PR.

    A PR appears on the pane when it is associated with an agent. The platform infers the association from what it already knows — an open PR whose head branch matches a branch an agent pushed from its worktree — and shows that provenance as inferred; the person can associate or dissociate a PR by hand, shown as asserted. Inference is conservative: an ambiguous match shows the PR unassociated rather than guessing, because a wrong association would render one agent's liveness against another's PR. Pull requests belong to a Squadron through the agents working them.

    Every fact on the pane is measured from the forge by the platform, on a cadence, never recalled by an agent: state, draft, title, author, branches, head commit, mergeability, review decision, the check rollup with failed check names, unresolved review threads, timestamps, and when it was last measured. The pane never guesses: an unknown mergeability shows as "?", a PR not yet measured shows as measuring, and an unreachable forge leaves the last-known facts in place with a staleness clock — never an outage rendered as "everything is fine" or "everything is dead." Measured facts are rebuildable from scratch; a person's associations are not lost when they are rebuilt.

    The pane is read-only toward the forge. It never merges, comments, closes or re-runs anything. Its one action opens the ordinary message composer to an associated agent, prefilled with the PR, its head commit, and a compact snapshot of the measured state, for the person to edit and send through the same path as any other message — so the pane can never hold state the agents do not know about.

    Rows are ordered attention-first — needs something (failing checks, conflicts, changes requested), then waiting (checks running, review pending), then green — and stable within a group: rows update in place and never move under the cursor. Closed and merged PRs stay briefly, then leave. Like every fleet surface, the pane merges every connected environment and names each PR's environment.

    The pane carries no workflow methodology. The prior-art dashboard computed readiness gates for one three-agent workflow; those do not ship. Whether a PR is "ready" by some workflow's rules is the workflow's content; the generic successor — named status checks any workflow can define, rendered with outcome and staleness — is a separate primitive, later. GitHub is the only forge today, behind a thin seam so a second one can follow.

    The pane is not a place to act on pull requests, not a readiness or gating system, and not the fleet-attention view; it is one pane beside the Fleet page and the inbox, designed so siblings can join it.

    Acceptance criteria

    Association

    1. A PR opened from a branch an agent pushed from its worktree appears on the pane within one measurement cycle, associated to that agent with provenance shown as inferred.
    2. A PR with no inferable agent does not appear until a person associates it; that association shows provenance as asserted; either kind can be removed.
    3. When inference is ambiguous, the PR shows as unassociated.

    Measurement

    1. Check completions are reflected within one measurement cycle even when the PR's own updated timestamp did not change.
    2. An unknown mergeability renders as "?" and never as mergeable; a PR not yet measured renders as measuring.
    3. When the forge is unreachable, every row keeps its last-known facts with a visible staleness clock, nothing renders green by default, and measurement resumes without a restart when the forge returns.
    4. Wiping the measured facts and re-measuring loses no person-asserted association.

    The pane

    1. Rows order attention-first and stay in stable order within a group; a row updates in place and never moves under the cursor.
    2. Twenty or more PRs render with fixed-height rows and no continuous repaint.
    3. Each row names its environment, and PRs from every connected environment appear on one pane.
    4. Closed and merged PRs remain for a bounded time, then leave.

    The action

    1. "Message agent" opens the composer to the associated agent, prefilled with the PR, its head commit and the measured state, and sends through the ordinary agent-message path; the pane performs no write to the forge of any kind.
    2. No readiness gate or workflow rule is computed or shown.

    Scenarios

    • A PR appears. The Builder in Billing Migration pushes billing/schema-v2 and opens a PR; within a cycle the pane shows it, associated to the Builder as inferred, with checks running. (AC1)
    • Checks finish quietly. CI completes without touching the PR; the row's check pill updates on the next cycle. (AC4)
    • The forge goes away. GitHub is unreachable for ten minutes; every row keeps its facts and shows "measured 10m ago"; nothing turns green; measurement resumes on its own. (AC6)
    • Nudging. The user clicks "Message agent" on a conflicting PR; the composer opens to the Builder with the PR, its head commit and "conflicting · 2 checks failing" prefilled; the user edits and sends. (AC12)

    History

    • 2026-08-17 — the brief approved by Jackson and posted as issue PR Pane v1: agent-associated PR visibility + "work this PR" nudge #6 (record): association auto-first, one nudge action, GitHub only behind a seam, no readiness gates.
    • 2026-08-19 — every fleet surface merges environments from day one (the cross-device position).
    • 2026-09-10 — rewritten as a definition: the Squadron dimension and the multi-environment requirement stated; repository tooling and the wireframe left to the record. Former brief acceptance criteria 1–8 → AC1, AC2, AC4, AC6, AC5, AC12, AC9, AC7.
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions