Skip to content

Let a flow driver find its running flow without the id - #1105

Merged
alexeyzimarev merged 5 commits into
mainfrom
flows-status-without-id
Sep 23, 2026
Merged

alexeyzimarev merged 5 commits into
mainfrom
flows-status-without-id

Conversation

@alexeyzimarev

@alexeyzimarev alexeyzimarev commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Closes #1103 — AI-3104

What & why

A driver whose harness aborted start_review_flow never receives the flow_run_id, and context compaction loses it later; either way the run keeps working with no way back to it. The two status tools take the id as optional and read the calling session's newest open flow instead: several open flows are listed to choose from, and none open falls back to the newest settled one so a failure the driver missed still reads as failed. The Codex kcap-flows registration and the bundled plugin descriptor carry tool_timeout_sec = 600, healed into entries kcap wrote earlier and never into edited or foreign ones. The four blocking tools, both flow skills and the README say up front what a harness abort means and which call recovers from it.

Where to look

The lookup calls GET /api/flows?requesting_session_id=…&state=all, which is kurrent-io/kcap-server#1982 and is not on the server yet; against today's server the bare call answers "cannot look up flows by session, pass the id". The row contract the CLI reads is posted on that issue. The bare call resolves a session on Claude Code and Codex only, since the JSON harnesses give the flows server no session identity; the guidance says so, and #1123 covers those harnesses.

Verification

  • Capacitor.Cli.Core.Tests.Unit: 3604 passed, 0 failed
  • Capacitor.Cli.Tests.Unit: 4621 passed, 0 failed
  • Capacitor.Cli.Tests.Integration / McpFlowsServerTests: 36 passed
  • dotnet publish -c Release: no IL2026/IL3050 warnings; dotnet build Capacitor.slnx: 0 warnings
  • Not verified end to end: a bare get_review_flow_status(wait: true) reaching a live run needs the server route.

🤖 Generated with Claude Code

alexeyzimarev and others added 2 commits September 22, 2026 10:05
…1103)

An entry kcap wrote earlier is healed to the new shape through the ownership lane; the fingerprint covers integer values, so a timeout the user set is kept.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…1103)

The lookup route, GET /api/flows?requesting_session_id=...&state=all, is kcap-server#1982 and is not on the server yet; an older server's 404 is worded as pass-the-id. The blocking tools' descriptions, both flow skills and the README carry the harness-timeout guidance.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-23T06:41:39.569781Z c1cb0a6 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Recover flow status by session when the run ID is unavailable

🐞 Bug fix ✨ Enhancement ⚙️ Configuration changes 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Resolve omitted flow IDs from the calling session without guessing between open flows.
• Give Codex flow tools a 600-second timeout while preserving customized registrations.
• Document harness-timeout recovery and cover lookup, schema, configuration, and error paths.
Diagram

sequenceDiagram
    participant C as Codex Config
    actor D as Flow Driver
    participant M as Flows MCP
    participant A as Flows API
    C-->>D: 600-second tool timeout
    D->>M: Status without run ID
    M->>A: List flows by session
    A-->>M: Newest-first flow rows
    alt One open flow
        M->>A: Read selected flow
        A-->>M: Flow status
        M-->>D: Status and result
    else Several open flows
        M-->>D: Candidate list
    else No open flows
        M->>A: Read newest settled flow
        A-->>M: Settled status
        M-->>D: Status and result
    end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Return the run ID before blocking
  • ➕ Eliminates recovery lookup ambiguity after a harness timeout
  • ➕ Avoids requiring a session-flow listing route for aborted starts
  • ➖ Changes the established start-tool contract that returns findings in the same call
  • ➖ Requires drivers to perform a separate wait step for every start
  • ➖ Does not recover IDs lost later through context compaction
2. Persist session-to-flow mappings locally
  • ➕ Works without the new server-side session lookup route
  • ➕ Could recover IDs immediately without an additional list request
  • ➖ Becomes stale across machines, processes, or server-side lifecycle changes
  • ➖ Needs synchronization and cleanup for concurrent flows
  • ➖ Cannot reliably represent flows started through another client

Recommendation: Keep the PR's server-backed session lookup and conservative ambiguity handling. It recovers both aborted starts and IDs lost later, while the Codex timeout reduces how often recovery is needed. Returning IDs before blocking would be cleaner for a future protocol revision, but it would disrupt the current tool UX; local caching is less authoritative. Merge should remain coordinated with the required server-side GET /api/flows?requesting_session_id=…&amp;state=all route.

Files changed (13) +565 / -36

Bug fix (1) +102 / -4
McpFlowsServer.csResolve status requests from session flows when IDs are missing +102/-4

Resolve status requests from session flows when IDs are missing

• Makes both status tools resolve omitted or blank flow IDs through the session flow-list endpoint. It selects one open flow, lists ambiguous candidates, falls back to the newest settled flow, handles route and authentication failures, and adds timeout recovery guidance to blocking tools.

src/Capacitor.Cli/Commands/McpFlowsServer.cs

Refactor (1) +16 / -12
McpSessionId.csSupport session resolution from captured requester context +16/-12

Support session resolution from captured requester context

• Refactors explicit session parsing and adds 'ResolveWithin' so long-lived servers can prefer an explicit argument while using their previously captured harness session without rereading the environment.

src/Capacitor.Cli/Commands/McpSessionId.cs

Tests (5) +395 / -9
CodexConfigTomlTests.csTest Codex flow timeout registration ownership +67/-0

Test Codex flow timeout registration ownership

• Verifies only 'kcap-flows' receives the timeout, previously owned entries are healed, and user-customized timeout values remain untouched and unclaimed.

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs

KcapMcpServersTests.csTest the exclusive kcap-flows timeout descriptor +7/-0

Test the exclusive kcap-flows timeout descriptor

• Confirms 'kcap-flows' is the only MCP server with a tool timeout and that its value is ten minutes.

test/Capacitor.Cli.Core.Tests.Unit/Mcp/KcapMcpServersTests.cs

McpFlowsServerTests.csPin the optional status-tool schema +11/-9

Pin the optional status-tool schema

• Updates integration schema assertions so review status accepts optional 'flow_run_id', 'session_id', and 'wait' arguments with no required fields.

test/Capacitor.Cli.Tests.Integration/McpFlowsServerTests.cs

FlowsDriverSchemaConformanceTests.csVerify status recovery schemas and timeout guidance +36/-0

Verify status recovery schemas and timeout guidance

• Checks both status tools expose optional string identifiers and all four blocking tools explain harness-timeout recovery using the appropriate status call.

test/Capacitor.Cli.Tests.Unit/Commands/FlowsDriverSchemaConformanceTests.cs

StatusWithoutFlowRunIdTests.csCover session-based flow status resolution +274/-0

Cover session-based flow status resolution

• Adds comprehensive tests for open and settled selection, ambiguity, waiting, explicit session canonicalization, blank and invalid IDs, missing sessions, unsupported server routes, and unauthorized responses.

test/Capacitor.Cli.Tests.Unit/Commands/StatusWithoutFlowRunIdTests.cs

Documentation (4) +43 / -8
README.mdDocument ID-free status recovery and Codex flow timeout +8/-4

Document ID-free status recovery and Codex flow timeout

• Explains the 600-second Codex registration timeout, optional status-tool flow IDs, session selection, ambiguity behavior, and recovery after harness-aborted calls. It also clarifies that only status tools support session fallback.

README.md

CHANGES.mdRecord session lookup and timeout design decisions +27/-0

Record session lookup and timeout design decisions

• Documents the failure scenario, flow-selection policy, server-route dependency, registration ownership behavior, and driver guidance behind the change.

docs/CHANGES.md

SKILL.mdTeach agent flows to recover after harness timeouts +4/-2

Teach agent flows to recover after harness timeouts

• Directs agents to call 'get_flow_status(wait: true)' instead of starting another flow after an aborted call. Updates the tool contract to describe optional flow and session IDs.

kcap/skills/agent-flows/SKILL.md

SKILL.mdTeach review flows to recover missing run IDs +4/-2

Teach review flows to recover missing run IDs

• Adds harness-timeout recovery guidance and updates review-flow rules and tool documentation for session-based status resolution.

kcap/skills/review-flows/SKILL.md

Other (2) +9 / -3
CodexConfigToml.csWrite MCP tool timeouts into Codex configuration +1/-0

Write MCP tool timeouts into Codex configuration

• Serializes a server descriptor's optional tool timeout as 'tool_timeout_sec' in its Codex MCP registration.

src/Capacitor.Cli.Core/Harness/Codex/CodexConfigToml.cs

KcapMcpServers.csAssign a ten-minute timeout to kcap-flows +8/-3

Assign a ten-minute timeout to kcap-flows

• Extends MCP server descriptors with an optional tool timeout and configures only 'kcap-flows' with a ten-minute budget.

src/Capacitor.Cli.Core/Mcp/KcapMcpServers.cs

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59f42b9779

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 31 to +33
new("kcap-flows", ["mcp", "flows"], NeedsProjectCwd: true,
"Structured AI agent flows — launches a SEPARATE hosted participant agent; requires login + a running daemon."),
"Structured AI agent flows — launches a SEPARATE hosted participant agent; requires login + a running daemon.",
ToolTimeout: TimeSpan.FromMinutes(10)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Propagate the timeout to the native Codex descriptor

Codex users who enable kcap through codex plugin add load kcap/.codex-mcp.json, but that descriptor's kcap-flows entry still contains only command and args; ToolTimeout is emitted only by CodexConfigToml. I verified with the installed Codex 0.144 CLI that a tool_timeout_sec value in a plugin MCP descriptor is honored (codex mcp get reports the configured value). Consequently, native-plugin users retain Codex's default timeout and can still have flow calls aborted despite this change, so the descriptor should carry the 600-second value too.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added in c525a37: kcap/.codex-mcp.json carries tool_timeout_sec: 600 on kcap-flows, pinned against the descriptor's ToolTimeout by McpCanonicalContractTests.Bundled_codex_mcp_json_carries_the_flows_tool_timeout.

Comment on lines +1262 to +1263
var sessionId = McpSessionId.ResolveWithin(arguments, requestingSessionId);
var url = $"{apiRoot}/api/flows?requesting_session_id={Uri.EscapeDataString(sessionId)}&state=all";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Support ID recovery in JSON-based harnesses

When the flows MCP server runs under Cursor, Copilot, Gemini, Kiro, OpenCode, or Antigravity, HarnessRequesterContext.Resolve() has no per-process session signal: HarnessRequesterContext.cs documents that KCAP_SESSION_ID is shell-only and may be inherited from a parent, while only Claude and Codex expose their own session IDs. Thus requestingSessionId here is null or wrong, and starts were attributed using that same value, so omitting flow_run_id cannot recover the correct run in those supported drivers despite the new universal tool/skill guidance. This needs a reliable per-harness session association or a locally persisted run ID rather than depending solely on requestingSessionId.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct as a limitation, and not fixable inside this PR: those harnesses export no per-process session signal, so their starts carry no requesting_session_id and no session-keyed lookup can find them. In 075e212 the tool descriptions, both skills and the README name Claude Code and Codex as the harnesses where the id may be omitted. A local run ledger for the rest is #1123.

@qodo-code-review

qodo-code-review Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Id-free flow recovery always fails 🔗 Cross-repo conflict ≡ Correctness
Description
ResolveStatusFlowRunIdAsync calls GET /api/flows?requesting_session_id=…&state=all, but the
pinned kcap-server exposes no collection GET route under /api/flows. Any status call without
flow_run_id therefore receives 404 and stops before reading the running flow, including the
harness-timeout recovery path introduced by this PR.
Code

src/Capacitor.Cli/Commands/McpFlowsServer.cs[R1262-1265]

+        var sessionId = McpSessionId.ResolveWithin(arguments, requestingSessionId);
+        var url       = $"{apiRoot}/api/flows?requesting_session_id={Uri.EscapeDataString(sessionId)}&state=all";
+        using var getCts = clock.CreateTimeoutSource(PerGetTimeout);
+        using var resp   = await client.GetAsync(url, getCts.Token);
Relevance

●● Moderate

The limitation is explicitly documented and gracefully reported, but recovery remains unavailable
until the server route ships.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR constructs the new collection request and handles 404 as an unsupported lookup, while the
pinned server's complete public flow route table contains only start and mutation POSTs plus a
per-ID GET. The tool schema also makes the ID optional, exposing the unavailable server dependency
to callers.

src/Capacitor.Cli/Commands/McpFlowsServer.cs[1254-1277]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[2316-2323]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public/Flows/FlowEndpoints.cs [38-98]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public/Flows/IFlowEndpointHandlers.cs [41-48]

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

## Issue description
The newly optional `flow_run_id` relies on a session-filtered flow-list endpoint that the pinned kcap-server does not implement, so ID-free status recovery always returns the unsupported-server error.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1250-1303]
- /cross_repos/kcap-server/src/Capacitor.Api.Public/Flows/FlowEndpoints.cs[38-98]

## Recommended Fix
Implement and release the authenticated `GET /api/flows` route in kcap-server with the exact query parameters, ordering, status semantics, and response fields consumed here, then coordinate deployment so it precedes or accompanies this CLI release. If that coordination is unavailable, keep `flow_run_id` required and do not advertise ID-free recovery until the server capability exists.

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



Remediation recommended

2. Malformed flow lists look empty ✓ Resolved 🐞 Bug ☼ Reliability
Description
ParseSessionFlows returns an empty list whenever a successful response lacks a flows array,
despite the caller only classifying thrown JsonExceptions as unreadable responses. When a server
returns valid JSON with an incompatible or incomplete shape, the status tool falsely says the
session started no flow instead of reporting protocol incompatibility, undermining the recovery path
this change introduces.
Code

src/Capacitor.Cli/Commands/McpFlowsServer.cs[R1288-1291]

+    static List<SessionFlow> ParseSessionFlows(string body) {
+        var flows = new List<SessionFlow>();
+        if (JsonNode.Parse(body)?["flows"] is not JsonArray rows) return flows;
+        foreach (var row in rows.OfType<JsonObject>()) {
Relevance

●●● Strong

Recent precedent accepts treating successful JSON missing required collections as protocol-invalid
rather than empty.

PR-#768

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The caller has an explicit unreadable-response branch only for JsonException, but the parser
returns an ordinary empty collection when flows is missing or has the wrong type. That empty
collection reaches the newly added chosen is null branch and produces the factually different
message that no flow was started.

src/Capacitor.Cli/Commands/McpFlowsServer.cs[1275-1285]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[1288-1303]

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

## Issue description
A successful flow-list response without the required `flows` array is treated as an empty history rather than an unreadable server response.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1275-1285]
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1288-1303]

## Recommended Fix
Validate that the response root is an object and that `flows` is an array before selecting a flow. Return the existing unreadable-flow-list error for invalid shapes, and add coverage distinguishing an empty valid array from a missing or wrongly typed `flows` property.

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


3. A timeout fixture narrates old behavior ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The documentation on
RegisterKcapMcpServers_adds_the_tool_timeout_to_an_owned_flows_entry_written_without_it describes
an entry written before timeout support and contrasts it with the current writer. That
history-dependent wording can become stale as ownership migration changes, whereas the lasting
constraint is that a claimed timeout-free entry must be healed.
Code

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[R415-417]

+    /// <summary>A flows entry kcap wrote before it carried a timeout, with the ledger claim taken
+    /// over that shape. The claim is a verbatim fixture: regenerated from the current writer it would
+    /// carry the timeout already, and the test would prove nothing.</summary>
Relevance

●●● Strong

The comment explicitly narrates historical writer behavior; replacing it with the invariant is a
straightforward maintainability fix.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2897915 prohibits change-history narration in comments. The newly added summary explicitly
describes what kcap wrote before the timeout existed and what the current writer would produce.

Rule 2897915: Avoid time-sensitive or process-reference metadata in code comments
test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[415-417]

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

## Issue description
The new fixture comment narrates earlier and current writer behavior rather than documenting only the durable compatibility invariant.

## Fix Focus Areas
- test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[415-417]

## Recommended Fix
Rewrite the comment to state that the verbatim fixture represents a claimed timeout-free owned entry and that the test verifies healing without regenerating the fixture. Remove temporal wording such as `before` and references contrasting it with the current writer.

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


4. Flow recovery hides lookup timeouts ✓ Resolved 🐞 Bug ☼ Reliability
Description
ResolveStatusFlowRunIdAsync applies PerGetTimeout to the session lookup but does not catch the
resulting OperationCanceledException. When the request exceeds 20 seconds, the exception bypasses
the local status-tool handling and reaches the outer dispatcher, which returns a generic internal
error instead of an actionable, retryable lookup failure while the flow may still be running.
Code

src/Capacitor.Cli/Commands/McpFlowsServer.cs[R1264-1265]

+        using var getCts = clock.CreateTimeoutSource(PerGetTimeout);
+        using var resp   = await client.GetAsync(url, getCts.Token);
Relevance

●●● Strong

Similar MCP timeout findings were accepted when cancellation escaped local tool handling.

PR-#344

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added session lookup creates a cancellation source with the 20-second per-request timeout and
passes its token to GetAsync, while the local tool handler catches only ArgumentException and
HttpRequestException. Any resulting OperationCanceledException therefore reaches the outer
dispatcher, which catches remaining exceptions and replaces them with a generic internal-error
response; the existing polling paths explicitly handle cancellation as a network failure,
demonstrating the missing handling in this request path.

src/Capacitor.Cli/Commands/McpFlowsServer.cs[1262-1266]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[471-474]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[68-99]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[1524-1534]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[1263-1266]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[474-482]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[68-94]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[1522-1535]

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

## Issue description
The omitted-flow-ID lookup uses a bounded cancellation token, but when the by-session `GetAsync` exceeds `PerGetTimeout`, its `OperationCanceledException` escapes the status-tool handler and becomes a generic internal error rather than an actionable lookup failure.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1263-1266]
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[471-474]
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1640-1648]

## Recommended Fix
Wrap the session-flow `GetAsync` in `ResolveStatusFlowRunIdAsync` with the same `HttpRequestException` and `OperationCanceledException` handling pattern used by the polling paths. Return a structured, retryable MCP tool error explaining that the flow lookup request timed out or failed, while preserving distinct caller-cancellation behavior if a caller token is introduced later.

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


View medium (1)
5. Three timeout tests bypass temp helpers ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The three new RegisterKcapMcpServers tests create method-local TempDir instances, and the
migration test writes files through File.WriteAllText and Path.Combine rather than TempDir
helpers. These additions extend manual lifecycle and path handling in a test class that should use
an injected temporary directory, making future fixture changes span two competing patterns.
Code

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[R420-422]

+        using var tmp = new TempDir();
+        var path = tmp.GetResolvedPath("config.toml");
+        File.WriteAllText(path, """
Relevance

●●● Strong

The repository enforces injected temporary-directory helpers, and these tests introduce competing
manual filesystem patterns.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rules 2767472 and 2808173 require test classes to use injected temporary-directory state and its
path/file helpers. The added tests allocate new TempDir() at lines 404, 420, and 453, while lines
422-432 directly write files and construct a path beneath that temporary root.

Rule 2767472: Use TempDir helper for all temporary filesystem state in tests
Rule 2808173: Use injected [TempDir] public required property in test classes instead of manual fields
test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[402-465]

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

## Issue description
The new timeout tests manually allocate `TempDir`, and the migration fixture writes temporary files without the helper APIs required by the test conventions.

## Fix Focus Areas
- test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs[402-465]

## Recommended Fix
Add the framework-injected `[TempDir] public required TempDir` property to the test class and replace method-local allocations with that property. Create the TOML and ownership-ledger fixtures through `TempDir.CreateFile` or the equivalent helper rather than `File.WriteAllText` and `Path.Combine`; migrate the class's remaining manual allocations as needed so it retains one consistent lifecycle pattern.

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


Grey Divider

Context sources
✅ Compliance rules (platform): 64 rules
✅ Cross-repo context — repo relationships
  Explored: repo: kurrent-io/kcap-server (sha: e44124cf)
Review mode: 🧠 Deep: This is a behavior-changing flow/MCP feature spanning lookup, session resolution, polling, schemas, Codex registration, and compatibility paths, with substantial logic and many independent defect opportunities.

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more'

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs Outdated
Comment thread test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs Outdated
Comment thread src/Capacitor.Cli/Commands/McpFlowsServer.cs Outdated
Comment thread src/Capacitor.Cli/Commands/McpFlowsServer.cs Outdated
Comment on lines +1262 to +1265
var sessionId = McpSessionId.ResolveWithin(arguments, requestingSessionId);
var url = $"{apiRoot}/api/flows?requesting_session_id={Uri.EscapeDataString(sessionId)}&state=all";
using var getCts = clock.CreateTimeoutSource(PerGetTimeout);
using var resp = await client.GetAsync(url, getCts.Token);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Id-free flow recovery always fails 🔗 Cross-repo conflict ≡ Correctness

ResolveStatusFlowRunIdAsync calls GET /api/flows?requesting_session_id=…&state=all, but the
pinned kcap-server exposes no collection GET route under /api/flows. Any status call without
flow_run_id therefore receives 404 and stops before reading the running flow, including the
harness-timeout recovery path introduced by this PR.
Agent Prompt
## Issue description
The newly optional `flow_run_id` relies on a session-filtered flow-list endpoint that the pinned kcap-server does not implement, so ID-free status recovery always returns the unsupported-server error.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[1250-1303]
- /cross_repos/kcap-server/src/Capacitor.Api.Public/Flows/FlowEndpoints.cs[38-98]

## Recommended Fix
Implement and release the authenticated `GET /api/flows` route in kcap-server with the exact query parameters, ordering, status semantics, and response fields consumed here, then coordinate deployment so it precedes or accompanies this CLI release. If that coordination is unavailable, keep `flow_run_id` required and do not advertise ID-free recovery until the server capability exists.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Known and stated in the description: the route is kurrent-io/kcap-server#1982, with the row contract posted there. Against today's server a bare call answers cannot look up flows by session … pass the flow_run_id, which is what the driver had to do before this change, so the schema change is additive and ships safely ahead of the route. Merge order is the maintainer's decision.

alexeyzimarev and others added 3 commits September 23, 2026 08:15
Codex reads a plugin descriptor entry into the same server config as config.toml, so the key is honoured there and a native-plugin install would otherwise keep the 300 s default.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A bare status call resolves the session on Claude Code and Codex only: the JSON harnesses give the flows server no session, so the guidance names the two; #1123 covers the rest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ows-status-without-id

# Conflicts:
#	docs/CHANGES.md
@alexeyzimarev

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: c1cb0a6130

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@alexeyzimarev
alexeyzimarev merged commit 2e126d7 into main Sep 23, 2026
8 checks passed
@alexeyzimarev
alexeyzimarev deleted the flows-status-without-id branch September 23, 2026 10:35
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.

Flows: recover a running flow without its id and warn before a harness timeout

1 participant