Skip to content

refactor(protocol): each area owns its published runtime capability list - #30641

Merged
brennanb2025 merged 6 commits into
mainfrom
brennanb2025/capability-lists-per-area
Oct 21, 2026
Merged

brennanb2025 merged 6 commits into
mainfrom
brennanb2025/capability-lists-per-area

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​184 $\color{#cf222e}{\Huge{\mathbf{−}}}$​2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​182
Prod 23 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​573 $\color{#cf222e}{\Huge{\mathbf{−}}}$​534 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​39

ELI5

Every feature that lets a paired Orca server tell clients "I support X" had to add a line to the same long list in one shared file. Parallel PRs kept colliding there. Now each area (agent sessions, terminal, browser, worktrees, ...) keeps its own list in its own file, and the shared file just combines them. Paired clients retain the same feature support. In Settings, the host details preview shows three capability names in the new area order; that display change is intended.

What Changed

Problem (developer-facing): src/shared/protocol-version.ts held RUNTIME_CAPABILITIES, one flat hand-appended array mixing about 20 areas plus 9 inline string literals, and src/shared/runtime-capability-constants.ts held 79 loose constants from about 15 areas. Every new wire capability appended to both, at the same spot, so it was the most-conflicted file in recent merges (33 merged, 15 closed and 9 open PRs touched it). Earlier work (#25839, and the files that say "Split out of protocol-version.ts") moved some areas out, but left the central list hand-kept.

After: each area module exports <AREA>_RUNTIME_CAPABILITIES next to its constants, and RUNTIME_CAPABILITIES is 20 spread lines, one per area. A new capability in an existing area edits only that area's file; the central list changes only when a new area is born.

  • New area files in src/shared/: agent-session-, browser-, terminal-, worktree-, task-source- (Jira, Linear, task context), source-control- (GitHub/GitLab ready-for-review, commit-message model), files-, host- (status, environments, shared control, updates, managed runtimes, SSH targets), mobile-, preflight-, workspace-ports-, ai-vault-runtime-capabilities.ts.
  • Extended: session-tabs-runtime-capabilities.ts (close-intent, inventory, and the client-only tab/proof deltas), terminal-quick-command-capabilities.ts (now owns its constant).
  • Already-split areas are spread unchanged (orcad, orchestration, automation, accounts, skills, agent launch, device key); the agent-session area rolls up its existing stop/create/surface/attention/resume pieces.
  • runtime-capability-constants.ts is deleted. Its direct importers are repointed, including the two CLI imports added on merged main. protocol-version.ts still exports every name it exported before (same values), so the ~180 files that import from it are untouched.
  • Constants a host adds only under a condition (browser headless/identity/certificate trust, managed server), client-only constants and the dark queued-messages flag stay out of their area's list, exactly as they stayed out of the central one.
  • Client lists (NATIVE_REMOTE_RUNTIME_CLIENT_CAPABILITIES, mobile/web/electron/desktop-renderer lists) are not changed.

Wire: no change from the merged main. The published capability set is identical: 179 strings on merged main 2fc2f92a386471ccfbe8277cea3df71d2f6ec0cf and current head e3e555118fb75ba3c7471afe422948f83753418d. Main's files.write.disk-precondition.v1 remains in the files area, and its new project-host-setup.host-target.v1 is preserved in the worktree area; the original test baseline remains 170 names. Independently evaluated RUNTIME_CAPABILITIES, the native client list and every protocol-version export from each Git revision: sorted published sets equal, no duplicate names, native list identical including order (9 entries), all 141 exports from merged main retained (including the original 138) and every previous value except the intentionally reordered host aggregate unchanged; 12 additional exports are the area arrays. No protocol version change.

Order — intended: the array's order changes (grouped by area). Feature gating checks membership (includes/filter). The Settings runtime host detail previews the first three capability names plus a count (runtime-environment-host-details.ts:96), so that preview shows three different names in the new order; the count is unchanged. This Settings preview-order change is intended. Raw status JSON from the CLI, local hosts and SSH hosts also exposes the grouped capability-array order; that order change is intended. Membership and counts match main for identical host conditions; runtime filters and conditional additions make the actual count host-specific.

Review path: full. This refactor exceeds the light-path size limits and touches published capability negotiation across independently updated desktop, server, phone and SSH peers. It requires the full review, exact-head PR workflow and real Electron QA.

Why

The common pattern is that the code owning a feature declares its own capability and the aggregate is collected, not hand-appended. TypeScript has no link-time registry, so the aggregate is one static spread per area. A self-registering design (each module registers at import time) was rejected: the published set would then depend on which modules each bundle (main, renderer, mobile, CLI) happened to import, which is a silent wire change, and the cross-version tests read RUNTIME_CAPABILITIES from released builds as a static array. Only moving the loose constants (and keeping the hand-appended central list) was rejected because the append point is what conflicts.

The new test protocol-version-published-capabilities.test.ts keeps a frozen baseline of the original 170 published names and checks that every baseline name remains published. Adding a capability requires no baseline edit, so feature additions do not recreate a central test edit hotspot. Deliberately retiring support requires an explicit baseline edit. The one-time before/after equality checks above still verify that this refactor preserves the published set, native client list order and all previous export values.

Linked Issue

N/A (maintainer refactor; tech-debt audit item G, PR 1 of the capability-registry plan).

Final main integration

On 2026-10-20, merged main 2fc2f92a386471ccfbe8277cea3df71d2f6ec0cf to resolve overnight conflicts, producing e3e555118fb75ba3c7471afe422948f83753418d. Main's new item-detail and queued-message-image-edit capabilities belong to the agent-session module; other additions flow through existing area arrays. Independent checks confirm 179 identical unique static names, all 141 main exports retained, unchanged client contracts in both sidebar modes, and the unchanged original 170-name baseline. All 35 targeted tests passed. The exact-head full PR workflow and its aggregate gate passed, as did every auxiliary workflow.

An independent reviewer checked every resolution difference and found the integration mechanical, with no new findings or changed shipped behavior beyond main. Under the coordinator's explicit ruling, the real QA below remains applicable; no fresh app run was performed after this merge. The screenshots depict the earlier comparison and its historical 172-static/179-runtime counts, not today's 179-static total. Hook changes to an incoming tracked document only adjust Markdown table padding.

Visual Proof

Earlier real comparative Electron QA completed on M4Air through qa-gate ticket 533, using built main 41fdd7e6d8301ff1faa956e8ecc6a8ef86cff10f and final 7c32100f8f60b66a7216f5f85a451492eefc1fe6, identical fixtures and a real paired headless host. Both roles published 179 names, with equal membership and exclusions (172 static names plus the same host-specific additions).

Intended Settings difference: main previews ai-vault.chat-fork-source.v1, jira.transition-fields.v1, jira.agent-access.v1 +176; final previews runtime.status.compat.v1, runtime.environments.v1, remote-runtime.shared-control.v1 +176. The grouped order is also visible in raw status JSON. Counts and support remain equal for the same host facts.

Flow Main Final
Paired server details — intended preview order Main: Paired server details — intended preview order Final: Paired server details — intended preview order

Setup executed once on each pin; ordinary terminal, quick command, real Grok idle/working/Done, and nonempty configured default tabs all completed. The review comment includes paired screenshots for those surrounding flows. With Grok selected, the first configured Check tab adopts that startup agent on both pins, retaining Check/Shell/Setup order; this is established behavior, not a new change.

Deferred presentation observation: main's completed Grok tab showed a prompt summary while final showed grok. The traced code is identical; main's original raw terminal title output was unavailable, so causality remains unresolved. The launcher explicitly accepted deferral with no PR regression established. Live QA covered macOS desktop/headless and real Grok terminal sessions; other agents, structured chat, Windows/Linux/SSH UI, mobile devices and native focus were not exercised live. All recorded rigs/drivers stopped and the ticket was released.

Testing

  • Automated tests added/updated, or explained why not below

  • New: src/shared/protocol-version-published-capabilities.test.ts (frozen 170-name baseline remains a subset of published capabilities; new additions need no baseline edit).

  • Review fix: ran that exact named file through the local test gate with Node and config/vitest.config.ts; 1 file and 1 test collected, 1 passed. The 170-name baseline is unchanged.

  • Ran locally: that test plus session-tabs-tab-delta, agent-status-run-capability, agent-chat-permission-host-support, terminal-image-viewer-env (51 passing). CI covers typecheck, lint and the full suite, including the cross-version wire suites.

  • One-time before/after dump of the published set and barrel exports, as above.

  • Earlier main integration: the capability baseline, shared disk-precondition contract and files RPC forwarding tests collected 16 tests across 3 exact named files; all passed through the local test gate. Final conflict integration: the capability baseline, CLI project setup and shared project-host target tests collected 33 tests across 3 exact named files; all passed through the local test gate. The original 170-name baseline is byte-identical; the independent final export proof is summarized above.

Review

Integration notes for open PRs touching these lists (none edited here):

Differences from the common pattern: the aggregate is still one line per area rather than collected automatically (intended: TypeScript has no link-time registry, and module side-effect registration would make the published set import-order dependent).

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Security, cross-platform, SSH, mobile, backwards compatibility and performance: capability gating is unchanged; the same strings are published to the same peers. The intended visible change is the Settings three-name preview order described above. Mobile imports one constant from its new area file.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots attached for the intended Settings preview change and surrounding flows
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • Full PR workflow green on final head: lint/typecheck, unit shards, cross-version wire, packages and aggregate gate; real Electron QA builds passed. No local lint/typecheck was run.

RUNTIME_CAPABILITIES now spreads one array per area instead of a flat
hand-appended list, and runtime-capability-constants.ts is split into
the areas that own each constant. The published set is unchanged and
pinned by an exact sorted test.
@brennanb2025
brennanb2025 marked this pull request as ready for review October 19, 2026 08:04
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8ba8b29f-3fb1-451f-a555-a2debce4fba6
📥 Commits

Reviewing files that changed from the base of the PR and between 7c32100 and e3e5551.

📒 Files selected for processing: 5
  • docs/reference/agent-browser-focus-isolation.md
  • mobile/src/session/mobile-structured-agent-session-host-support.ts
  • src/shared/agent-session-runtime-capabilities.ts
  • src/shared/protocol-version.ts
  • src/shared/runtime-capability-constants.ts
💤 Files with no reviewable changes: 1
  • src/shared/runtime-capability-constants.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

📝 Walkthrough

Runtime capability identifiers and grouped arrays now reside in feature-specific modules. The protocol module builds RUNTIME_CAPABILITIES from those arrays and re-exports selected capabilities; the former constants module is removed. A regression test checks that the registry contains every capability in a fixed published-capability baseline. Related imports and comments now reference the feature-specific modules. Two documentation tables were reformatted without changing their contents.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to e3e55

This refactor keeps the published runtime capabilities unchanged. One test-coverage gap remains open: the preservation test would not catch removal of one file capability. It is safe to merge, but consider closing that gap.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the main change: moving ownership of published runtime capability lists to individual areas. It is concise and specific.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description is complete and follows the required template. It explains the change and rationale, documents the maintainer issue exception, provides visual proof, testing details, revi…
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 30 files. (1 skipped: 1 unsupported.)

Full details: Description check

Explanation

The pull request description is complete and follows the required template. It explains the change and rationale, documents the maintainer issue exception, provides visual proof, testing details, review context, compatibility notes, and checklist status. It also clearly identifies historical QA versus current-head validation.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments: 1
src/shared/protocol-version-published-capabilities.test.ts: 1

89-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the existing disk-write precondition to the published baseline.

files.write.disk-precondition.v1 was already in the PR base's RUNTIME_CAPABILITIES, so it is part of the frozen published set. Without it, removing the capability later can pass the preservation test.

Proposed change
   'files.resolve-terminal-path.cross-workspace.v1',
+  'files.write.disk-precondition.v1',
   'folder-workspace.path-status.v1',

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 474c9cad-b0c1-4b29-ae15-734d6a352052
📥 Commits

Reviewing files that changed from the base of the PR and between 57de7ea and df779b5.

📒 Files selected for processing: 9
  • src/main/agent-hooks/server/server-status-application.ts
  • src/main/agent-hooks/server/server-status-update.ts
  • src/main/daemon/pty-subprocess-spawn-file-foreground.test.ts
  • src/main/daemon/terminal-host-process-inspection.test.ts
  • src/main/providers/local-pty-child-process-verdict.test.ts
  • src/main/providers/local-pty-provider-foreground-process.test.ts
  • src/shared/files-runtime-capabilities.ts
  • src/shared/protocol-version-published-capabilities.test.ts
  • src/shared/protocol-version.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

@brennanb2025

brennanb2025 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Current-head review refresh — 2026-10-20. Main's overnight capability additions conflicted with the removed central registry. Merged main 2fc2f92a386471ccfbe8277cea3df71d2f6ec0cf into the reviewed branch, producing e3e555118fb75ba3c7471afe422948f83753418d. Area ownership and the intended Settings preview order remain unchanged.

Independent narrow review found no lost main changes or new findings: main and final publish the same 179 unique static names, preserve all 141 main exports (including original 138) apart from intended aggregate order, retain native/client lists in both sidebar modes, and keep the original 170-name baseline byte-identical with additions allowed. New item-detail and queued-message-image-edit constants are in the agent-session owner. 35 tests across three exact named files passed. The current full PR workflow passed on this exact head, including aggregate gate; every auxiliary workflow passed too.

The independent reviewer confirmed a mechanical merge with no shipped behavior change beyond incorporation of main. Under the coordinator's explicit instruction, earlier real M4Air QA remains applicable and was not rerun. The screenshots and test counts in the earlier review below are historical: they show 7c32100f… versus 41fdd7e6…, 172 static / 179 runtime names; today's 179 static total is a different quantity. No new runtime total is claimed. The deferred terminal-title observation and stated live-platform limitations remain unchanged. All processes from that QA were stopped and its ticket released.

Earlier completed full review and real QA screenshots

Every new server capability previously required editing the same central list, so unrelated feature PRs repeatedly conflicted. The list is now assembled from its owning areas. Paired clients retain the same support; Settings intentionally previews three different capability names in the new area order.

Full review completed on 7c32100f8f60b66a7216f5f85a451492eefc1fe6 (full path: size and cross-version publication exclude the light path). Correctness, architecture, performance and final readiness checks found no remaining required fixes.

  • Fixed: the test now requires every name in the frozen original 170-name baseline to remain published. Additions require no test edit; deliberate retirement still changes the baseline. Main's two new capabilities were retained in their owning files during final conflict resolution.
  • Verified: independent main/branch evaluation found exactly the same 172 static names, no duplicates, all 139 existing exports retained with unchanged values apart from intended aggregate order, and unchanged client lists. The final targeted run passed 33 tests in three named files. The full PR workflow passed on this exact head, including static analysis, unit shards, cross-version wire tests and aggregate gate; the headless platform workflow also passed after authorized infrastructure retries.
  • Real QA: qa-gate admitted ticket 533 on M4Air. Built main 41fdd7e6d8301ff1faa956e8ecc6a8ef86cff10f and final head used identical fixtures, hidden Electron and a real paired headless host. Both host roles published 179 names with identical membership and exclusions; protocol stayed 3, compatibility floor 2. Setup ran once, ordinary terminals and quick commands worked, and real signed-in Grok went from idle to yellow working to green Done with QA_AGENT_OK. All recorded QA processes stopped and the ticket was released.

Deferred observation: completed Grok tab titles differed (main's prompt summary versus final's grok). The traced title and notice code is byte-identical and independent of capability ordering. Final raw terminal title output matches its UI; main's original raw output was unavailable after relaunch, so causality remains unresolved. The launcher explicitly deferred this as a presentation observation, with no PR regression established. The missing Enjoying Orca card on final was explained by the driver's earlier Later click and its cooldown. Provider welcome text also varied.

Baseline default-tab behavior: with setup sh setup.sh and templates Check (npm run check) / Shell (blank), creating a workspace with Grok selected produced Check, Shell, Setup on both pins, Check initially active, then preserved Shell selection on revisit; setup ran once. The selected startup agent intentionally adopts the first template slot, including its title. Consequently Check ran Grok, and this QA does not claim npm run check executed. The creation and default-tab source is identical across pins; this is established behavior accepted by the launcher.

Limits: live QA covered macOS desktop/headless hosts and the real Grok terminal route. Other agents, structured chat, Windows/Linux/SSH UI, mobile devices, every conditional combination and native focus were not exercised live here; source parity and CI cover their unchanged contracts. The initial frame before setup completed was not captured for the nonempty default-tab fixture. No runtime performance measurement is claimed.

For Brennan's review

The intended visible difference is Settings' first-three preview: main shows ai-vault.chat-fork-source.v1, jira.transition-fields.v1, jira.agent-access.v1 +176; final shows runtime.status.compat.v1, runtime.environments.v1, remote-runtime.shared-control.v1 +176. Raw status JSON uses the same intended area order; membership and counts stay equal for the same host facts.

Flow Main Final
Paired server details — intended preview order Main: Paired server details — intended preview order Final: Paired server details — intended preview order
Ordinary flows compared on main and final
Flow Main Final
Local server details Main: Local server details Final: Local server details
Workspace setup, once Main: Workspace setup, once Final: Workspace setup, once
Ordinary terminal Main: Ordinary terminal Final: Ordinary terminal
Quick command Main: Quick command Final: Quick command
Real Grok idle Main: Real Grok idle Final: Real Grok idle
Real Grok working Main: Real Grok working Final: Real Grok working
Real Grok Done; title observation above Main: Real Grok Done; title observation above Final: Real Grok Done; title observation above
Configured default tabs; first-slot adoption Main: Configured default tabs; first-slot adoption Final: Configured default tabs; first-slot adoption
Default Shell tab Main: Default Shell tab Final: Default Shell tab
Shell remains active after revisit Main: Shell remains active after revisit Final: Shell remains active after revisit

The three code judgment points are the one-spread-per-area aggregate, the additions-allowed frozen baseline, and the first-three Settings preview.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant