Phase B/C/D/E: PR shepherding pipeline + Vibe Check#1
Conversation
Ship the auto-PR-comment loop end-to-end:
- RepoWatchTask polls GitHub, hashes PR state, consults an NDJSON
idempotency ledger, emits PrOpened/PrUpdated/PrClosed on an
internal EventBus. Per-PR MonitorPrTasks subscribe and re-prompt
the agent on each update. Idempotent `devdev repo watch/unwatch`.
- `devdev_ask` MCP tool: universal approval seam. Agent calls it
with kind={post_review,post_comment,request_token,question};
daemon routes through ApprovalGate and surfaces a host-derived
short-lived `gh` token on approval.
- `devdev init` Vibe Check scribe writes `.devdev/*.md` preference
files; `devdev preferences {list,edit}` for inspection.
- Scenario S07 covers the user-surface plumbing.
- ROADMAP/cap-doc/CHANGELOG refreshed.
Validated Win + WSL: clippy clean, full test suite green except
pre-existing WinFSP env failure.
| // If the per-task `auto_approve` overrides the daemon's | ||
| // policy, swap the active approval channel so `devdev_ask` | ||
| // bypasses prompts for this task. | ||
| if policy != self.approval_policy { |
There was a problem hiding this comment.
Replacing self.approval_gate / self.approval_handle here changes the daemon-wide channel, not just this task's behavior. After the first task/add with a different policy, every later devdev_ask call goes through the new policy because DaemonToolProvider holds the same shared Arc<Mutex<ApprovalGate>>. That means one PR task can silently flip another task from Ask to AutoApprove/DryRun (or vice versa). This needs per-task approval state instead of mutating the shared gate in DispatchContext.
|
|
||
| // Ledger consult — if we've published this exact state | ||
| // before (across the lifetime of the daemon), skip. | ||
| let already = self |
There was a problem hiding this comment.
This ledger short-circuit means a fresh watcher will skip publishing anything for an already-open PR whose state hash was recorded in a previous daemon run. Since spawn_event_coordinator only creates MonitorPrTasks from observed events, and Daemon::save_checkpoint() only persists the filesystem (not tasks), restarting the daemon and re-running repo watch leaves unchanged open PRs with no monitor task at all until a later update arrives. The watcher needs a bootstrap path that recreates monitor tasks for currently open PRs without re-emitting duplicate reviews.
- scheduler in run_up calling poll_all_tasks every 5s - last_polled self-throttle in RepoWatchTask - ToolCall/ToolCallUpdate.status now Optional (Copilot CLI omits on initial tool_call) - ACP idle_timeout bumped to 300s for live agents
- dispatch.rs: per-task auto_approve no longer mutates the daemon-wide approval gate (was leaking policy across all tasks). Documented as TODO until per-session approval routing exists. - repo_watch.rs: a fresh task instance now republishes PrOpened on first observation even when the ledger already has the state hash, so MonitorPrTasks get respawned after daemon restart. Ledger still suppresses duplicate records on the same instance. - updated unit test ledger_dedups_across_restart to assert the new (correct) republish-on-restart semantics. - adjusted other repo_watch tests to set with_interval(0) so the new poll() self-throttle doesn't suppress the second poll in 2-poll tests.
Dogfood PR: this is the loop reviewing itself.
Pipeline
devdev repo watch <owner>/<repo>polls GitHub, hashes PR state, consults an NDJSON idempotency ledger, and emitsPrOpened/PrUpdated/PrClosedevents on an internalEventBus.MonitorPrTasksubscribes and re-prompts the ACP agent on each update.devdev_askMCP tool:kind={post_review,post_comment,request_token,question}->ApprovalGate-> short-livedghtoken on approval.Vibe Check
devdev initruns a scribe that writes.devdev/*.mdpreference files in the user's voice.devdev preferences {list,edit}for inspection.~/.devdevprecedence with repo-wins dedup.Coverage
repo/watchlifecycle.Validated Win + WSL: clippy clean, full test suite green except pre-existing WinFSP env failure (
live_workspace_cwd).Posted comments below — if any — were generated by this PR's own pipeline. Meta.