Skip to content

Durable PR monitoring with feedback delivery and fallback ownership - #194

Closed
ronak-guliani wants to merge 1271 commits into
mainfrom
feat/pr-monitor-stack-main
Closed

Durable PR monitoring with feedback delivery and fallback ownership#194
ronak-guliani wants to merge 1271 commits into
mainfrom
feat/pr-monitor-stack-main

Conversation

@ronak-guliani

Copy link
Copy Markdown
Owner

Summary

Ship end-to-end durable PR monitoring (stacked #181-#184) onto main: provider-neutral observe-only monitors, durable feedback delivery and structured reporting, automatic ownership / review handoff, and fallback maintenance threads on orchestration V2.

Problem

PR follow-up was UI- or turn-owned, GitHub-shaped, and easy to lose across restarts. There was no durable server-owned monitor, no stable feedback revisions/deliveries, and no safe path when the owning thread was missing—so remediation could steer active turns, drop events, or race ownership.

UX Flow

User / agent creates or enables a PR monitor
└─ Server owns one canonical monitor per (provider, host, repo, number)
   ├─ Adaptive poll → durable snapshot + readiness
   ├─ Ingest feedback revisions (cursor only after success)
   ├─ Queue remediation behind active work (V2 send, never steer in-turn)
   ├─ Optional auto-own on PR create + review-thread handoff
   └─ If owner missing/unavailable: fallback maintenance thread
      (prepared worktree, exclusive ownership, force only with approval)

Human retains merge control; ready PRs stay slowly monitored.

Solution

Built on orchestration V2 + multi-provider PullRequestService. Migrations 050-053. GitHub is the first monitorSnapshot provider.

Stack references

PR Scope
#181 Contracts + durable observe-only monitor
#182 Feedback delivery + structured reporting
#183 Automatic ownership + review handoff
#184 Fallback maintenance threads

Note on base

Head is base/pr-monitor-v2 tip (includes V2 prerequisite lineage plus #181-#184). A full merge of current main into this tip is large and conflict-heavy; resolve main drift in follow-up before merge if required.

Powered by Grok 4.5 (Copilot CLI).

tsouth89 and others added 30 commits August 9, 2026 14:16
pingdotgg#5782)

Co-authored-by: tsouth89 <tsouth89@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…stalled providers are found (pingdotgg#5074)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…thread (pingdotgg#5901)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…5928)

Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ing (pingdotgg#5659)

Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…g#4849)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria <maria@kuuro.net>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
mwolson and others added 25 commits August 10, 2026 18:04
…r's scope (pingdotgg#5406)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Keep the git action control disabled when the branch is up to date
- Omit open PR menu entries and remove their link-opening behavior
- Update logic tests for the new states
…sPinned

Main owns migration numbering: 036_ProjectionThreadsPinned landed on main,
so the v2 migrations shift from 036-044 to 037-045. Release path runs all
of main's migrations first, then the v2 stack.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Port thread pinning (pingdotgg#5312) into the orchestration-v2 command pipeline:
  thread.pin/unpin commands, thread.pinned/unpinned events, pinnedAt on the
  v2 thread state and projected shells, promotion semantics (pin clears
  settle/snooze, settle clears pin) matching the v1 decider, and client
  pin/unpin operations in the v2 dispatch style.
- Port the regenerated-title context anchoring (pingdotgg#5365) into
  ThreadTitleRegenerationService: pin the first user message ahead of the
  retained tail when the digest is truncated.
- Re-apply the right-panel controls positioning from pingdotgg#5260 to the v2
  ChatView title bar controls.
- Repair merge artifacts: committed conflict markers in BranchToolbar,
  duplicate capability keys, duplicate CommandPalette import, v1 turn
  naming in DiffPanel's focus-refresh effect, onSend signature merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Match progress button spacing and single-line height to static git actions
rerere replayed stale resolutions during the rebase and committed nested
conflict markers in several files. Restore the branch-intended v2 shapes
and re-graft main's compatible additions (pending-card opacity comments,
theme-editor keybinding test, mobile scroll re-arm effects from pingdotgg#5566).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eysetIndex

Main owns migration numbering: 037_ProjectionTurnsKeysetIndex landed on
main (pingdotgg#5493), so the v2 migrations shift from 037-045 to 038-046.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Native subagent observability (pingdotgg#5219), wired per its spec's v2 merge plan:
- getWorkflowScript RPC re-homed onto the v2 WS surface (contracts, rpc
  group, ws handler, auth scope, client atom).
- AgentsPanel fed by the spec's mapper swap: projectedSubagentsToRuntime
  maps orchestration-v2 subagent entities into the panel model;
  deriveAgentPanelModel's v2Projection leg is now live and the v1 fold
  never runs. Agents surface wired into ChatView + RightPanelTabs.
Other ports and reconciliations:
- Shell reconnect-loop fix (pingdotgg#5561) ported into the v2 shell sync
  (same-session resubscribes resume from the in-memory cursor), with the
  cursor-resume regression test adapted to v2 fixtures.
- Mobile end-follow latch (pingdotgg#5566) ported onto the v2 ThreadFeed.
- Claude ede_diagnostic interrupt classification (pingdotgg#5557) ported into
  ClaudeAdapterV2 (aborted_tools/aborted_streaming => interrupted; CLI
  telemetry never becomes the failure banner). pingdotgg#5559 needs no v2 port
  (unknown system subtypes are already ignored).
- Plan sidebar removed from the v2 ChatView/ChatComposer per main's
  plans-fold-into-chat rework (pingdotgg#5558); rightPanelStore stays at main's
  surface set.
- SettingsPanels rebuilt as main's refactored version plus the branch's
  composer-context setting; sidebar snooze respects the time format
  (pingdotgg#4438 follow-through).
- v1-only leftovers deleted: zombie v1 adapters/ingestion/tests the v2
  rewrite removes, the v1-bound transfer-budget CI harness (pingdotgg#5350, needs
  a v2 rebuild), and main's v1 client pagination machinery (pingdotgg#5493 client
  side; the 037 keyset migration is kept — server-side v2 windowing is a
  follow-up).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rebase kept the LegendList 3.3.3 upgrade and patch from pingdotgg#5449 and the
mobile end-follow latch from pingdotgg#5566, but the v2 MessagesTimeline/ChatView
still carried the branch's blunt any-gesture-breaks-follow listeners.
Port main's pingdotgg#5566 web mechanics onto the v2 follow architecture:

- resolveTimelineIsAtEnd measures the 40px follow re-arm band from real
  geometry (contentLength/scroll/scrollLength minus the composer inset),
  keeping the isNearEnd fallback for older state shapes.
- Follow now breaks only on gestures that can actually leave the live
  edge: upward wheel with overflowing content, touch drags that exited
  the end band, scrollbar drags vs content clicks, and keyboard
  navigation (PageUp/Home/ArrowUp) — previously keyboard scrolling never
  broke follow and the next stream chunk yanked the view back down.
- Listener attach retries across frames so a thread switch cannot mount
  the list without its opt-out listeners.

Deliberately not ported: pingdotgg#5449's shouldRestorePosition disclosure
anchoring and follow-gated maintainScrollAtEnd — the v2 timeline keeps
maintainScrollAtEnd={false} with its own follow scrolls and anchor
system; flipping that core is a separate change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gdotgg#5449)

Complete the pingdotgg#5449 architecture on the v2 timeline, following the
LegendList author's direction to lean on the list's native mechanisms
instead of app-side scroll layers:

- maintainScrollAtEnd is enabled and owned by LegendList, gated off only
  while the user reads history (liveFollowEnabled), while a sent turn
  anchors near the top (anchoredEndSpace), or during the two-frame settle
  of a fold toggle.
- maintainVisibleContentPosition compensates size changes natively
  ({data, size, shouldRestorePosition}); fold toggles anchor compensation
  to the toggled row via a disclosure anchor key, so the trigger stays
  under the pointer instead of the viewport chasing the end.
- ChatView's hand-rolled streaming follow (double-rAF scrollToEnd on
  every data change) is gone; the app now only owns streaming
  adjustments during anchored-end-space mode, mirroring main.
- timelineLiveFollowEnabled state mirrors the follow refs so the
  render-visible gate switches native follow off when a gesture breaks
  follow and back on when the viewport returns to the end band.

Timeline tests updated to assert the native-ownership invariants.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Keep success feedback visible in the Git action control for 10 seconds
- Move the running elapsed timer into the panel menu slot
…s with v2

Post-rebase reconciliation sweep:
- Sidebar: main's folded Sidebar.tsx/Sidebar.logic.ts adapted to v2 shells
  (latestRun/runtime naming, waiting status instead of monitoring), with
  subagent-thread filtering and main's pinned-reorder helpers re-exported
- Pinned drag reorder (pingdotgg#5581) ported into v2: thread.pin orderKey +
  thread.pin.reorder command, thread.pin-reordered event, Orchestrator fold,
  ProjectionStore/Maintenance, client-runtime commands and shell mapping
- Project favicon (pingdotgg#4849-era) and defaultThreadEnvMode flowed through v2
  contracts (OrchestrationProjectShell, application event payloads)
- ChatView: main's pingdotgg#5592 header props, pull-request right-panel surfaces,
  liveAgentCount badge (pingdotgg#5745) wired into the v2 panel layout
- enableAssistantStreaming -> enableLegacyTokenStreaming rename applied to
  v2 RunExecutionService and replay testkit
- Removed v1 zombies resurrected by the rebase (provider service/reaper/
  ingestion + v1 layer tests, server.test.ts, integration harness)
- routeTree: main's tree + branch's /settings/scheduled-tasks route
- Misc marker-sweep syntax repairs (rpc.ts, entities.ts, localApi.test.ts,
  rightPanelStore.test.ts, GitManager.test.ts, mobile model menu helpers)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 038-040

Main released ProjectionThreadsPinOrderKey (038),
ProjectionProjectsDefaultThreadEnvMode (039) and
ProjectionProjectFaviconPath (040), so the branch-private v2 stack shifts
up by three. Registry ids were already 41-49; this renames the files and
identifiers to match and updates the ledger expectations and through-id
boundaries in the migration tests (released boundary 37 -> 40).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- a6c9b41 (agents open pasted images): ClaudeAdapterV2 now grants the
  attachments dir alongside cwd via additionalDirectories and appends
  '[Attached ... is saved at: path]' lines to the turn text so tools can
  dereference pasted images (pixels alone are not tool-readable).
- 5bb8c03 (settle leaves monitors running): thread.settle now joins
  archive/delete in the provider-session detach set, so PR monitors, dev
  servers and subagent fleets stop when the user parks the thread. The
  settle guard already rejects active runs, and serialized dispatch closes
  the re-engage race the v1 fix handled with onlyIfSettled.
- e70cdb4 (Claude resume handshakes) and 2c7267a (reaper vs live
  background subagents) are already covered structurally in v2: results
  are turn-scoped with explicit zero-turn handshake drops, and idle
  release is pinned while background work is pending.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e panel-visibility merge

The keep-both merge nested main's plan-surface migration test inside a
branch popover test and dropped the threadPanelVisibilityByThreadKey key
from the migration results. Restore main's test body and include the
branch's (empty) visibility map in the expected persisted shape.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n text

Follow-up to the pingdotgg#5757 port: start and steer turns now append the
'[Attached ... is saved at: path]' line, so the adapter fixtures assert it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The round-3 reconciliation took main's ChatHeader wholesale and wired its
full prop set, resurrecting the scripts/open-in/git-actions cluster the
branch had deliberately relocated into the thread panel. Restore the
79-line slim header (project favicon + name + thread title) and its
minimal ChatView call. pingdotgg#5592's header actions stay a documented v2
follow-up, as decided in round 2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add provider-neutral monitor contracts, GitHub monitor snapshots, SQLite
durability with leases/adaptive polling, start/stop/status/list RPC, and a
basic PR detail monitor strip. Observe-only: no feedback delivery yet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(server): durable PR monitor feedback delivery and reporting

Add feedback items/revisions/deliveries with debounce and circuit breakers,
queue-mode V2 delivery via ThreadManagementService, MCP context/report tools,
status audit fields, and migration 051. Never steers active turns.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): make PR feedback delivery state atomic

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): land PR B monitor feedback review blockers

Cursor advances only after feedback ingest, durable ingest without
owner, MCP project scope, transactional disposition reports, poll-only
recheck updates, per-monitor delivery serialization, and items rename.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(server): PR monitor ownership and review-thread handoff

Associate created PRs with owning threads when enabled, support single-owner transfer with audit events, and link review threads via submitFindings RPC/MCP without concurrent modifying owners.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): preserve PR monitor ownership handoffs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): address PR monitor ownership review

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(server): PR monitor fallback maintenance threads

Launch exclusive fallback maintenance threads via ThreadLaunchService with prepared PR worktrees when the owner is missing or unavailable. Records durable fallback ledger entries, transfers single ownership, and never dual-owns concurrent modifiers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): reapply tip PR monitor review hardenings on rebuilt stack

Restore fail-closed ownership/fallback, durable feedback edges, MCP
scope, and client wiring after rebasing the A–D stack onto updated B.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): address PR 184 review comments on fallback monitor

Remove the duplicate ThreadManagement import, restore atomic feedback
pending/circuit state updates, wait for prepared-run completion before
ownership transfer, and keep wake-prompt blocker summaries bounded.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(server): harden PR monitor fallback launch against dual-run and stale heads

Cooldown only applies when the recorded owner is still available (force bypasses it).
Fallback materializes the PR head via preparePullRequestThread before launching on
that worktree, and exclusive lease + CAS ownership transfer serialize concurrent
launches while abandoning prep threads that lose the race or fail.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 12, 2026 19:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@github-actions github-actions Bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Aug 12, 2026
@ronak-guliani

Copy link
Copy Markdown
Owner Author

Closing: this PR incorrectly used base/pr-monitor-v2 as the head tip, so GitHub diffed the entire orchestration V2 lineage (~1271 commits / multi‑MB) against main, not just PR monitoring.

Monitor-only scope is the four stacked merges (#181#184, on the order of ~6–7k LOC). Those commits do not apply cleanly to current main because they depend on:

main still has the older github PR helpers and lacks apps/server/src/pullRequest/* and pullRequestMonitor/*.

Next step options:

  1. Land V2 + PullRequestService prerequisites on main, then open a monitor-only PR with just feat(server): durable observe-only PR monitor foundation #181feat(server): PR monitor fallback maintenance threads #184, or
  2. Keep reviewing the stack on base/pr-monitor-v2 until that base is what merges to main.

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

Labels

vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.