Skip to content

Roadmap — June 2026 (~4 weeks)

Four parallel threads coming out of the May session, sequenced so each week builds on the last. Estimates use Fibonacci story points (1, 2, 3, 5, 8) calibrated to ~10–15 points/week of capacity for one engineer.

Threads at a glance

ThreadScopeTotal points
A. Close the Linear loop3 PRs8
B. Quinn PR autonomy (close_pr / close_issue)2 PRs5

| C. Clawpatch on any repo (worktree checkouts) | 4 PRs | 13 | | D. Dashboard phase 3 (trace view + layout + drawer) | 3 PRs | 13 | | E. Cleanup + release hygiene | 4 small PRs | 5 | | Total | 16 PRs | 44 |


Week 1 (~13 pts) — Unblock the autonomous loop

Focus: get Quinn to a fully self-sufficient review loop AND wire Linear inbound to its first consumer. Both are short, both unblock follow-on work.

B1 — pr_inspector close_pr action (3 pts)

Root cause of the #556 cascade was Quinn deciding to file an issue asking someone else to close a PR because she had no close_pr tool herself. Add it.

  • Files: src/api/pr-inspector.ts, src/executor/executors/deep-agent-executor.ts (tool schema), workspace/agents/quinn.yaml (toolbelt + prompt)
  • Actions: close_pr, close_pr_as_not_planned, reopen_pr
  • Auth: same @protoquinn[bot] App identity already in use for reviews
  • Test plan: smoke a self-PR close on a draft test PR

B2 — pr_inspector close_issue action — ✅ SHIPPED (PR #787)

Same shape as B1, but for issues. Quinn's bug_triage skill was filing issues asking for issue closure because she couldn't close them herself.

  • Files: extend the route from B1 + tool schema
  • Actions: close_issue, close_issue_as_not_planned, reopen_issue, comment_on_issue
  • Prompt update: bug_triage resolves "already_fixed" / "duplicate" / "stale" by closing directly with a linking comment instead of filing a meta-issue

Shipped as lib/github-issues.ts closeIssue() + IssueCloserPlugin. The close-the-loop landed as an event-driven consumer that closed repo#githubIssueNumber with a linking comment rather than a Quinn-driven pr_inspector action. (That completion-event consumer belonged to the board integration, since removed; the underlying closeIssue() helper remains reusable for the agent-driven bug_triage resolution path described above.)

A1 — Wire linear.* inbound to Ava (2 pts)

Webhooks → bus is done (May session). channels.yaml Linear routes are still commented out. Uncomment them + map to Ava with skill hint linear_handle. Smallest possible change to make events stop falling into the void.

  • Files: workspace/channels.yaml (uncomment + reshape), workspace/agents/ava.yaml (add linear_handle skill + tools)
  • Skill hint: messages → agent.skill.request with targets: [ava], skill: linear_handle
  • Test plan: trigger a Linear comment, observe Ava dispatching

A2 — AppUserNotification handler in Ava (3 pts)

The Agent SDK envelope shape we landed in #545 publishes message.inbound.linear.agent.{action}. Ava needs to know what to do with each — issueMention and issueCommentMention reply via linear.reply.{issueId}, issueAssignedToYou triages.

  • Files: workspace/agents/ava.yaml (new linear_agent_respond skill with systemPromptOverride for each notification type)
  • Tools scoped to: linear_list_issues, linear_get_issue, linear_add_comment (already exists), chat_with_agent for fleet-agent delegation

E1 — Apply publish.yml to release-tools (1 pt)

Copy the protoPatch publish workflow to protoLabsAI/release-tools. Same pattern, no surprises.

E2 — Apply publish.yml to protoCLI (1 pt)

Same as E1 for protoLabsAI/protoCLI. Makes future proto releases follow the same git tag → publish flow.

E3 — Restore A2A agents in /api/agents/runtime (1 pt)

The new endpoint groups by (agentName ?? executor.type) but A2A executors register via registerDefault (not per-skill), so protopen and ORBIS are missing from the dashboard. Extend ExecutorRegistry to expose default registrations too, or pull from the existing /api/agents yaml as a fallback for the dashboard.

  • Files: src/executor/executor-registry.ts (add listDefault()?), src/api/agents-runtime.ts

Week 1 deliverable: Quinn never files a "please close this" issue again. Ava starts reacting to Linear comments. Three more repos publish on git tag.


Week 2 (~10 pts) — Linear close-the-loop + release hygiene cleanup

A3 — Board done → Linear comment (3 pts) — GitHub analog ✅ SHIPPED (PR #787)

This item belonged to the board integration, since removed. The GitHub analog — close-the-loop via IssueCloserPlugin (PR #787) — did ship: a completion event closed the originating repo#githubIssueNumber with a comment linking the shipped PR. The Linear-specific bridge side was never wired and is moot now that the board integration is gone.

E4 — Trusted Publishing migration for protoPatch (2 pts)

Replace the Classic Automation token with OIDC-based Trusted Publishing per npm's docs. Required because:

  1. Trusted Publishing has no secret to leak or rotate
  2. Provenance attestation is stronger (workflow identity tied to repo+branch)
  3. Sets the pattern other published packages migrate to
  • Steps: configure on npmjs.com/package/@protolabsai/protopatch/access; remove env: NODE_AUTH_TOKEN from publish.yml; verify next publish succeeds without the token; finally delete the org-level NPM_TOKEN
  • Reference: https://docs.npmjs.com/trusted-publishers

E5 — Trusted Publishing for release-tools + protoCLI (2 pts)

Same migration as E4 for the other two packages now that they publish.

A3.5 — Linear webhook delivery logs surface (1 pt)

Smaller follow-on: add [linear] event=issueCommentMention delivered to <agent> to the per-event log line so we can debug routing without grep-ing for the topic name.

Reserve: 2 pts for spillover from week 1 (B1/B2/A2 are agent-side and may bleed)

Week 2 deliverable: Linear is fully bidirectional. Quinn dispatches on Linear @mentions land back in Linear as comments. All three packages publish without token credentials.


Week 3 (~13 pts) — Clawpatch on any repo

The biggest single thread. Today clawpatch_review only works for repos hard-coded in the built-in mount map (protoWorkstacean / protoCLI / mythxengine). Adding on-demand checkout makes Quinn's structural review work for every repo she reviews.

C1 — Design doc + RFC (2 pts)

Write docs/explanation/clawpatch-checkouts.md covering:

  • Source of truth: GitHub tarball API (GET /repos/{owner}/{repo}/tarball/{ref})
  • Cache: /data/checkouts/<owner>-<repo>/<sha>/ — content-addressed by ref
  • Cache invalidation: LRU eviction at 5 GB or 50 entries (whichever first)
  • Security: enforce repo against workspace/projects.yaml allow-list (same as create_github_issue); no symlink traversal in tarball extract
  • Concurrency: per-(repo, sha) mutex so the same PR head doesn't extract twice
  • TTL: rebuild if checkout is older than 24h (lets us pick up base branch drift even with the same sha)

Get sign-off before implementing.

C2 — Implement on-demand fetch + extract (5 pts)

src/api/clawpatch.ts extends resolveRepoPath():

  1. If repo is in the built-in mount map → use it (today's behavior)
  2. Else: extract <repo>@<since> to /data/checkouts/<repo>-<sha>/
  3. Return the extracted path to clawpatch
  • Files: src/api/clawpatch.ts, new lib/checkout-cache.ts
  • Uses makeGitHubAuth() for the tarball download (same App credentials as everything else)
  • Unit tests on the cache helpers (LRU eviction, content-address shape, tarball-vs-symlink rejection)

C3 — Cache cleanup ceremony (3 pts)

Daily ceremony at 03:00 UTC that prunes the checkout cache to the LRU limit + deletes anything older than 7 days. Lives in workspace/ceremonies/clawpatch-cache-cleanup.yaml as a function executor (no agent needed — pure janitorial).

C4 — Quinn prompt update + drop the built-in mount map (3 pts)

  • Quinn's pr_review prompt removes the "v1 only handles protoWorkstacean / protoCLI / mythxengine" caveat
  • src/api/clawpatch.ts removes the BUILT_IN_REPO_PATHS map (everything goes through the checkout cache)
  • Documented migration: keep the built-in paths as the cache's fast path for the three already-mounted repos

Week 3 deliverable: Quinn's structural review works against escape-from-qud, protoContent, homelab-iac, anything in the managed-repos allowlist.


Week 4 (~13 pts) — Dashboard phase 3

Now that /system shows the live system, phase 3 turns it into a debugger.

D1 — Skill-trace view (5 pts)

/system/trace/:correlationId — for any agent.skill.request we've seen in the WS history buffer, render the full causal chain:

  10:42:01.123  message.inbound.github.opened.534   github

  10:42:01.180  agent.skill.request                  router
      ↓ targets=[quinn]
  10:42:01.215  agent.runtime.activity.skill.start   skill-dispatcher
      ↓ skill=pr_review
  10:42:01.530  deep-agent:quinn tool calls=[pr_inspector, clawpatch_review]

  10:42:04.213  agent.runtime.activity.skill.complete (3098ms)

  10:42:04.290  agent.skill.response.{corrId}        skill-dispatcher

Langfuse-style waterfall. Click-to-jump to Langfuse for the LLM call detail.

  • Files: dashboard/src/components/SkillTrace.tsx, new bus-history endpoint GET /api/bus/history?correlationId=... that returns the last N msgs matching that ID
  • Bus-history backend: in-memory ring buffer in src/event-bus/history-recorder.ts, capped at 10k events with 30-min TTL

D2 — Force-directed layout (3 pts)

Concentric rings break down at >30 nodes. Swap to a force-directed layout via @xyflow/elk or dagre. Keep the visual hierarchy (agents attractor in center, services repel to perimeter).

  • Files: dashboard/src/components/SystemGraph.tsx
  • Layout reruns on topology change but not on activity change (otherwise nodes jitter when an agent dispatches)

D3 — Edge inspection drawer (5 pts)

Click a pulsing edge → side panel opens showing the last N messages that traveled on that topic with payload preview + jump-to-trace.

  • Files: dashboard/src/components/MessageDrawer.tsx, extend the WS subscription to retain history per-topic
  • "Jump to trace" → routes to /system/trace/:correlationId from D1

Week 4 deliverable: /system is the primary debugging surface. docker logs is the fallback, not the front line.


Cross-thread principles

  • One PR per phase. Don't batch — each PR ships independently green.
  • Bus contract changes go via plugin publishes/subscribes declarations. No silent topic introductions.
  • Activity events are best-effort. A failed bus publish must never break a running skill (#565 set this rule — keep it).
  • All new endpoints declared in the plugin's contract. Phase 3 will probably show "endpoints with no consumer" cleanly.
  • Roadmap is a guide, not a contract. If a thread reveals real architectural change needed, file it as a separate roadmap doc and re-sequence.

Out of scope for this roadmap

  • GraphQL on top of the bus (interesting but big — separate quarter)
  • Multi-node BusBridgePlugin to NATS/Redis (only when actually needed)
  • Quinn voice / Discord-native PR review surface (different shape entirely)

protoWorkstacean — a switchboard, not an agent.