Skip to content

[AI-1762] §2.7 A2 cli mirror: report runtime_transport on AgentRegistered - #631

Merged
realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-1762-runtime-transport-cli
Aug 20, 2026
Merged

realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-1762-runtime-transport-cli

Conversation

@realtonyyoung

Copy link
Copy Markdown
Collaborator

What & why

AI-1762 §2.7 A2 cli mirror — the daemon half of the validated runtime_transport fact. The server side merged in kcap-server#1567: the server derives the transport it expects a launch to run on and validates the daemon's reported value on AgentRegistered. This PR makes the daemon actually report that value.

How

  • AgentRegistered (Cli.Core Models.cs) gains a trailing string? RuntimeTransport = null — additive name-bound field, wire-safe both skew directions, picked up automatically by the source-gen CapacitorJsonContext.
  • AgentInstance gains a computed RuntimeTransport property: Runtime is CodexAppServerHostedAgentRuntime ? "app-server" : "pty" (reusing CodexTransportDecision.AppServer/.Pty). The codex app-server runtime is the only app-server transport; every other runtime — PTY codex, PTY claude, and all ACP vendors — is pty. Deriving from the runtime instance means initial registration and every reconnect re-registration report the same value (the same instance survives a reconnect).
  • ServerConnection.AgentRegisteredAsync gains a trailing runtimeTransport arg, threaded from both call sites in AgentOrchestrator (initial RegisterAgentAsync and reconnect ReRegisterAgentsAsync) as agent.RuntimeTransport.

Scope

Server-first: kcap-server#1567 is merged, so this is safe to land now. It's dormant in practice until B6 turns on the v2 advertisement (no app-server launches happen before that — v1 app-server is retired and v2 isn't advertised yet), so every launch reports pty today; app-server starts flowing when B6 lands. The wire values "pty"/"app-server" are the cross-repo literal contract with the server's RuntimeTransports.

Tests

  • CodexAppServerHostedAgentRuntimeTests.AgentInstance_reports_app_server_transport_for_the_app_server_runtime — the app-server runtime → app-server.
  • AgentOrchestratorVendorTests.ReRegister_reports_pty_transport_for_a_pty_codex_runtime — a PTY codex runtime → pty end-to-end through AgentRegisteredAsync (proves the transport rides the runtime type, not the vendor).

🤖 Generated with Claude Code

…ered

The daemon half of the validated runtime_transport fact (server side merged in
kcap-server#1567). The daemon now reports the transport each hosted agent launched
on so the server can validate its own launch decision.

- AgentRegistered (Cli.Core Models) gains a trailing nullable RuntimeTransport —
  additive, wire-safe both skew directions, source-gen serialized.
- AgentInstance.RuntimeTransport: "app-server" iff the runtime is the codex
  app-server runtime, else "pty" (PTY codex, PTY claude, all ACP vendors). Derived
  from the runtime instance so initial + reconnect re-registration agree.
- ServerConnection.AgentRegisteredAsync + both AgentOrchestrator call sites (initial
  RegisterAgentAsync and reconnect ReRegisterAgentsAsync) thread agent.RuntimeTransport.

Server-first and safe now; dormant until B6 enables v2 advertisement (all launches
report "pty" until then). Wire values "pty"/"app-server" are the cross-repo contract.

Tests: app-server runtime -> "app-server"; a PTY codex runtime -> "pty" end-to-end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 20, 2026

Copy link
Copy Markdown

AI-1762

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Report runtime transport on AgentRegistered from CLI daemon

✨ Enhancement 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Add runtime_transport field to AgentRegistered for server-side validation
• Derive transport from runtime type and send on register + re-register
• Add unit tests covering app-server vs PTY transport reporting
Diagram

graph TD
  AI["AgentInstance"] --> AO["AgentOrchestrator"] --> SC["ServerConnection"] --> M["AgentRegistered model"] --> SV("Server")
  T["Unit tests"] --> AI
  T --> AO
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use an enum (or dedicated value object) instead of string literals
  • ➕ Stronger typing internally; reduces accidental typos
  • ➕ Easier to extend with additional transports later
  • ➖ Still needs a stable wire representation; adds mapping code on the daemon side
  • ➖ Cross-repo coordination required anyway; server already expects specific literals
2. Persist transport at launch time (store on AgentInstance) rather than deriving from runtime type
  • ➕ Explicit source of truth; avoids reliance on runtime type checks
  • ➕ Could support future cases where transport differs from runtime class
  • ➖ More plumbing through launcher construction paths
  • ➖ Higher risk of drift between initial registration and reconnect unless carefully preserved
3. Let the server infer transport solely from vendor/runtime metadata (no daemon reporting)
  • ➕ No wire-contract change and fewer daemon updates
  • ➖ Defeats the validation goal (can't detect mismatches between expected vs actual transport)
  • ➖ Harder to reason about as launches diversify (app-server vs PTY vs future transports)

Recommendation: Keep the PR’s approach: add a trailing nullable wire field and derive the value from the runtime instance type. It minimizes plumbing, remains skew-safe, and ensures initial registration and reconnect re-registration stay consistent because the runtime instance is stable across reconnects.

Files changed (8) +60 / -8

Enhancement (3) +18 / -5
Models.csAdd RuntimeTransport to AgentRegistered wire model +5/-1

Add RuntimeTransport to AgentRegistered wire model

• Extends the AgentRegistered record with a trailing nullable RuntimeTransport field. Documents expected literals ("pty" | "app-server") and preserves wire-compat via name-bound trailing parameter.

src/Capacitor.Cli.Core/Models.cs

AgentOrchestrator.csCompute and send runtime transport on register and re-register +10/-2

Compute and send runtime transport on register and re-register

• Adds AgentInstance.RuntimeTransport computed from the runtime type (CodexAppServerHostedAgentRuntime => app-server, otherwise pty). Threads the value into both initial registration and reconnect re-registration AgentRegisteredAsync calls.

src/Capacitor.Cli.Daemon/Services/AgentOrchestrator.cs

ServerConnection.csThread runtimeTransport into AgentRegisteredAsync payload +3/-2

Thread runtimeTransport into AgentRegisteredAsync payload

• Extends AgentRegisteredAsync with an optional runtimeTransport parameter and passes it into the AgentRegistered payload sent to the server hub method.

src/Capacitor.Cli.Daemon/Services/ServerConnection.cs

Tests (5) +42 / -3
CodexAppServerHostedAgentRuntimeTests.csTest app-server runtime reports app-server transport +13/-0

Test app-server runtime reports app-server transport

• Adds a unit test asserting AgentInstance.RuntimeTransport returns the app-server literal when using the Codex app-server hosted runtime. Imports the services namespace to construct AgentInstance in the test.

test/Capacitor.Cli.Daemon.Tests.Unit/Harness/Codex/CodexAppServerHostedAgentRuntimeTests.cs

AgentOrchestratorLocalAttachTests.csUpdate local attach test stub for new AgentRegisteredAsync signature +1/-1

Update local attach test stub for new AgentRegisteredAsync signature

• Updates TripwireServerConnection override to accept the new optional runtimeTransport parameter so existing local-attach tests compile and continue to track registration calls.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorLocalAttachTests.cs

AgentOrchestratorVendorTests.csTest PTY codex runtime reports pty transport on re-register +19/-0

Test PTY codex runtime reports pty transport on re-register

• Adds an end-to-end re-registration test verifying a PTY codex runtime reports the pty transport through AgentRegisteredAsync. Ensures transport is derived from runtime type rather than vendor identity.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorVendorTests.cs

CaptureServerConnection.csCapture runtime transport values from AgentRegisteredAsync calls +7/-1

Capture runtime transport values from AgentRegisteredAsync calls

• Extends the capture server connection to accept runtimeTransport and record it per registration call. Adds an AgentRegisteredTransports list used by tests to assert the reported transport.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/CaptureServerConnection.cs

SeqCaptureServerConnection.csUpdate sequence capture stub for new AgentRegisteredAsync signature +2/-1

Update sequence capture stub for new AgentRegisteredAsync signature

• Updates the SeqCaptureServerConnection override signature to include the optional runtimeTransport parameter for compilation compatibility.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/SeqCaptureServerConnection.cs

@qodo-code-review

qodo-code-review Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. RuntimeTransport references Codex harness ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
AgentInstance.RuntimeTransport (in Services/AgentOrchestrator.cs) branches on
CodexAppServerHostedAgentRuntime and returns CodexTransportDecision.*, which are Codex-harness
types. This introduces vendor-specific logic into shared Services/, violating the vendor isolation
requirement.
Code

src/Capacitor.Cli.Daemon/Services/AgentOrchestrator.cs[R108-109]

+    public string RuntimeTransport =>
+        Runtime is CodexAppServerHostedAgentRuntime ? CodexTransportDecision.AppServer : CodexTransportDecision.Pty;
Evidence
Rule 2 requires vendor-specific logic to stay within that vendor’s Harness/<Vendor>/ directory.
The PR adds RuntimeTransport in Services/AgentOrchestrator.cs that explicitly depends on Codex
harness types, and those types are defined under Harness/Codex/, demonstrating vendor-specific
coupling introduced outside the harness directory.

CLAUDE.md: Vendor-Specific Code Must Live Only Under That Vendor’s Harness Directory
src/Capacitor.Cli.Daemon/Services/AgentOrchestrator.cs[103-109]
src/Capacitor.Cli.Daemon/Harness/Codex/CodexTransportDecision.cs[15-18]
src/Capacitor.Cli.Daemon/Harness/Codex/CodexAppServerHostedAgentRuntime.cs[44-52]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Vendor-specific Codex transport logic was added to shared `Services/` code via `AgentInstance.RuntimeTransport`.

## Issue Context
Compliance requires vendor-specific functionality to live only under `Harness/<Vendor>/`. The new implementation directly references Codex harness types (`CodexAppServerHostedAgentRuntime`, `CodexTransportDecision`) from `Services/AgentOrchestrator.cs`.

## Fix Focus Areas
- src/Capacitor.Cli.Daemon/Services/AgentOrchestrator.cs[103-110]
- src/Capacitor.Cli.Daemon/Harness/Codex/CodexTransportDecision.cs[15-18]
- src/Capacitor.Cli.Daemon/Harness/Codex/CodexAppServerHostedAgentRuntime.cs[44-52]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can copy the agent prompt from any finding and feed it to your IDE agent

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli.Daemon/Services/AgentOrchestrator.cs Outdated
Replace the type-switch on CodexAppServerHostedAgentRuntime in the shared
AgentOrchestrator with a polymorphic IHostedAgentRuntime.RuntimeTransport
member: "pty" is the universal default on the interface, and only the Codex
app-server runtime overrides it to app-server. Keeps vendor-specific logic
under Harness/Codex/ and out of Services/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

Addressed the vendor-isolation finding in 63b2acbb: the transport decision now lives on the runtime itself. IHostedAgentRuntime.RuntimeTransport defaults to "pty" (the universal label every PTY/ACP runtime reports), and only CodexAppServerHostedAgentRuntime overrides it to app-server. AgentInstance.RuntimeTransport now forwards to Runtime.RuntimeTransport, so Services/AgentOrchestrator.cs no longer type-switches on a Codex harness type — vendor-specific logic stays under Harness/Codex/. Daemon builds clean (0 warnings); both transport tests pass.

@realtonyyoung
realtonyyoung merged commit 21bf10d into main Aug 20, 2026
6 checks passed
@realtonyyoung
realtonyyoung deleted the tonyyoung/ai-1762-runtime-transport-cli branch August 20, 2026 21:25
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