Skip to content

Expose declared plans through the sessions MCP recall tools - #1135

Merged
alexeyzimarev merged 8 commits into
mainfrom
alexeyzimarev/ai-3036-plan-ledger-recall-repo-level-open-plans-and-session-plans
Sep 24, 2026
Merged

alexeyzimarev merged 8 commits into
mainfrom
alexeyzimarev/ai-3036-plan-ledger-recall-repo-level-open-plans-and-session-plans

Conversation

@alexeyzimarev

Copy link
Copy Markdown
Member

Closes #1128 — AI-3036

What & why

A session that dies mid-plan leaves a task ledger recall cannot reach: a summary carries only the captured plan text, kcap-plans prompts on every call and is shut out of unattended review flows, and nothing finds a plan without a session id in hand. The read-only kcap mcp sessions server now relays the server's plan reads — list_repo_plans lists a repository's open (or all) declared plans with each one's next task and the liveness of its attached sessions, get_declared_plans reads one plan by id or every plan a session touched — and get_session_summary points at the session's plans through declared_plans, fetched beside /recap under a bound and dropped on any failure. The recap and plans skills teach an agent to judge done-ness from finished rather than is_complete (which only says nothing was withheld from the view) and to resume a plan in an order that never snapshots from a partial view, never declares the document from another checkout, and adopts last. The server half is kurrent-io/kcap-server#2009; against a server without the route, list_repo_plans answers with a plain "not yet" message, and where finished is absent the CLI derives it as total_known && completed == total && is_complete.

Where to look

HandleSessionSummaryAsync: the plans call starts before the recap read and is awaited after it, so a stalled /plans can hold a summary for at most the 10 s bound but never fails it. The resume procedure in kcap/skills/plans/SKILL.md is ordered around data-loss traps in the ledger's write path; keep its order if you edit it.

Verification

Before the merge of main: unit 4670/4670 (two session-start hook tests failed under a load average above 50 and passed alone), integration 301/301 at --maximum-parallel-tests 2 (the stdio tests, pre-existing ones included, flake at full parallelism on a loaded host), dotnet publish -c Release with zero IL2026/IL3050. On the merged tip: McpSessionsServerTests 75/75 and KcapMcpRegistryReviewFlowTests 16/16 (the registry-set mutation check fails Sessions_server_advertises_exactly_its_unattended_safe_tool_set when either tool is dropped), integration McpSessionsServerTests 18/18, scripts/check-linear-ids.sh clean. The 404, fail-open and recap-fails paths are pinned by WireMock integration tests; the with-route path has not been driven against a live server, since none carries the route until the server PR ships.

🤖 Generated with Claude Code

alexeyzimarev and others added 7 commits September 23, 2026 17:16
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The plans server prompts on every call and is shut out of unattended review flows, so recall could not reach a plan a dead session left behind.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
BuildRepoSessionsUrl and BuildRepoPlansUrl repeated the same 11-line repo/cwd-hash block verbatim.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An agent recapping a dead session had no way to learn a task ledger existed. The lookup is bounded and fails open, since the stdio loop is serial.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Declaring a plan's document from another worktree forks the plan, and a task snapshot sent from a partial view destroys what the caller cannot see; the resume procedure is ordered around both.

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

The plans route answers for a session's whole continuation chain, so every description that names the session says so.

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

chatgpt-codex-connector Bot commented Sep 23, 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-23T20:29:53.132239Z 286d6b9 PR opened
ℹ️ 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.

@linear-code

linear-code Bot commented Sep 23, 2026

Copy link
Copy Markdown

AI-3036

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expose declared plans through sessions MCP recall

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

Grey Divider

AI Description

• Adds read-only MCP tools for discovering repository plans and retrieving complete declared
 ledgers.
• Enriches session summaries with bounded, fail-open plan progress pointers.
• Documents safe plan completion and resumption workflows with comprehensive test coverage.
Diagram

sequenceDiagram
    actor Agent
    participant MCP as Sessions MCP
    participant Recap as Recap API
    participant Plans as Plans API
    Agent->>MCP: Recall sessions or plans
    alt Repository or plan lookup
        MCP->>Plans: Request plan data
        Plans-->>MCP: Plans and progress
    else Session summary
        par Fetch recap
            MCP->>Recap: Request recap
            Recap-->>MCP: Summary entries
        and Bounded plan lookup
            MCP->>Plans: Request session plans
            Plans-->>MCP: Plan details or failure
        end
    end
    MCP-->>Agent: Recall result
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Expose reads through kcap-plans
  • ➕ Reuses the existing plan-focused MCP server and its domain terminology.
  • ➕ Keeps all plan operations behind one MCP endpoint.
  • ➖ The server prompts on every call and is unsuitable for unattended review flows.
  • ➖ Repository-level discovery would still need a new read path and safe-tool classification.
  • ➖ Mixes passive recall with write-capable plan mutation operations.
2. Embed full plans in session summaries
  • ➕ Lets agents orient and inspect tasks with one tool call.
  • ➕ Avoids a separate plan-detail request for session-based recall.
  • ➖ Cannot discover abandoned plans without first knowing a session ID.
  • ➖ Inflates summary responses with documents and complete task lists.
  • ➖ Couples summary availability more tightly to the plans route.

Recommendation: Keep the PR's thin read-only relays in the sessions MCP server. They support unattended recall, add repository-level discovery, preserve a stable detail response shape, and enrich summaries without making recap success depend on plan availability.

Files changed (10) +1499 / -35

Enhancement (1) +206 / -19
McpSessionsServer.csRelay declared-plan reads through the sessions MCP server +206/-19

Relay declared-plan reads through the sessions MCP server

• Adds repository plan listing and plan-detail tools with shared repo resolution, validation, stable array responses, and legacy-server messaging. Session summaries now fetch plan pointers concurrently under a 10-second bound, fail open on plan errors, and derive 'finished' for older servers.

src/Capacitor.Cli/Commands/McpSessionsServer.cs

Tests (2) +287 / -2
McpSessionsServerTests.csCover plan recall over the MCP stdio boundary +138/-2

Cover plan recall over the MCP stdio boundary

• Verifies tool advertisement, repository routing, legacy 404 handling, stable plan arrays, summary enrichment, fail-open plan lookups, and recap error precedence.

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

McpSessionsServerTests.csTest plan URL validation and summary projection +149/-0

Test plan URL validation and summary projection

• Covers repository plan query construction, plan/session selector validation, tool schemas, declared-plan projection, malformed inputs, and backward-compatible 'finished' derivation.

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

Documentation (5) +1004 / -12
README.mdDocument the expanded sessions MCP plan recall surface +5/-3

Document the expanded sessions MCP plan recall surface

• Updates the sessions MCP tool count and documents repository plan listing, declared-plan retrieval, summary pointers, and repo-resolution behavior.

README.md

2026-09-21-ai3036-plan-ledger-recall-cli.mdAdd the implementation plan for plan-ledger recall +936/-0

Add the implementation plan for plan-ledger recall

• Adds the task-by-task design, wire contracts, safety constraints, testing strategy, and verification procedure used to implement the feature.

docs/superpowers/plans/2026-09-21-ai3036-plan-ledger-recall-cli.md

README.mdList all sessions MCP recall tools +6/-1

List all sessions MCP recall tools

• Expands the plugin README table to cover session navigation and the two declared-plan recall tools.

kcap/README.md

SKILL.mdTeach agents to safely resume declared plans +26/-4

Teach agents to safely resume declared plans

• Adds an ordered resume workflow that avoids cross-checkout plan forks and destructive snapshots from partial views. Clarifies checkout-sensitive declarations and read-only recall through the sessions server.

kcap/skills/plans/SKILL.md

SKILL.mdTeach recap workflows to discover and assess plans +31/-4

Teach recap workflows to discover and assess plans

• Adds plan-oriented recall triggers, tool guidance, completion semantics, compatibility rules, and examples for interpreting partial plan views.

kcap/skills/recap/SKILL.md

Other (2) +2 / -2
plugin.jsonBump the Claude plugin version to 1.11.0 +1/-1

Bump the Claude plugin version to 1.11.0

• Advances the plugin version for the updated recap and plans skill content.

kcap/.claude-plugin/plugin.json

KcapMcpRegistry.csRegister plan recall tools as unattended-safe +1/-1

Register plan recall tools as unattended-safe

• Adds 'list_repo_plans' and 'get_declared_plans' to the sessions server's read-only review-flow allowlist.

src/Capacitor.Cli.Core/KcapMcpRegistry.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: 286d6b9468

ℹ️ 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 +408 to +409
internal static string BuildSessionPlansUrl(string baseUrl, string sessionId) =>
$"{baseUrl}/api/sessions/{Uri.EscapeDataString(sessionId)}/plans";

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 Reject dot-segment session IDs

When get_declared_plans receives session_id: "." or "..", Uri.EscapeDataString leaves the value unchanged and the HTTP URI normalizes the dot segment, so the request targets /api/sessions/plans or /api/plans instead of the session-plans endpoint. Validate these values (or canonicalize session IDs as SessionPlansClient does) before constructing the URL, just as this change already does for plan_id.

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.

Fixed in 917b600 — BuildSessionPlansUrl rejects . and .. with the same ArgumentException shape as the plan_id guard, and since the summary handler now builds that URL before any request, get_session_summary is covered by the same check. Unit test BuildDeclaredPlansUrl_rejects_a_dot_segment_session_id.

Comment on lines +292 to +294
using var recap = await client.GetAsync(recapUrl);
var body = await recap.Content.ReadAsStringAsync();
var plans = await plansTask;

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 Cancel the plans request when recap retrieval fails

If the recap request throws while the parallel plans request is still stalled, control enters the catch without awaiting or cancelling plansTask; disposing plansCts does not signal cancellation and also removes its scheduled timeout. The lookup can therefore outlive the tool call until the shared HttpClient timeout, and repeated recap failures can accumulate background requests. Cancel and observe the plans task on this exception path so the advertised 10-second bound applies on every exit.

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.

Fixed in 917b600 — the recap read now runs inside a try/finally: every exit, including a thrown recap request, cancels plansCts and awaits the plans task (which never throws), so the lookup ends with the tool call instead of outliving it. Pinned by Get_session_summary_returns_a_failed_recap_without_waiting_for_a_stalled_plans_lookup: against the previous handler it failed at 11.2 s; it now returns well under 5 s and the next stdio request is not held.

@qodo-code-review

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

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Action required

1. Failed recaps leave plan requests running ✓ Resolved 🐞 Bug ☼ Reliability
Description
HandleSessionSummaryAsync starts plansTask before awaiting /recap, but an exception from the
recap request or body read bypasses the task's only await, and leaving the using scope disposes
plansCts without cancelling it. On recap transport failures, the handler returns while the
/plans request remains active on the shared client, allowing subsequent calls in the serial MCP
loop to accumulate background requests until their independent timeouts finish.
Code

src/Capacitor.Cli/Commands/McpSessionsServer.cs[R289-292]

+            using var plansCts  = new CancellationTokenSource(TimeSpan.FromSeconds(10), time);
+            var       plansTask = FetchDeclaredPlansAsync(client, BuildSessionPlansUrl(baseUrl, sessionId), plansCts.Token);
+
+            using var recap = await client.GetAsync(recapUrl);
Relevance

●●● Strong

Accepted precedents prioritize bounded best-effort requests and preventing abandoned asynchronous
HTTP work.

PR-#480
PR-#136

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The secondary /plans request is started at lines 289–290, while its only await occurs at lines
292–294 after both the recap request and body read succeed. The HttpRequestException handler at
lines 307–308 returns directly when either recap operation fails, bypassing that await; the dispatch
loop can then serve another request while the best-effort plans operation remains active because
disposing its cancellation-token source does not itself request cancellation.

src/Capacitor.Cli/Commands/McpSessionsServer.cs[55-70]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[281-309]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[312-322]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[288-308]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[312-321]

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

## Issue description
`HandleSessionSummaryAsync` starts the best-effort `/plans` request before `/recap`, but an exception from the recap request or body read bypasses the only `await plansTask`. Disposing `plansCts` does not cancel its token, so repeated recap failures can leave plans requests running after their tool calls return and accumulate background HTTP work.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpSessionsServer.cs[288-309]
- test/Capacitor.Cli.Tests.Integration/McpSessionsServerTests.cs[330-387]

## Recommended Fix
Track whether `plansTask` has been consumed and ensure every exit path after its creation cancels and observes it. Wrap recap request and status processing in a `try`/`finally`; if the plans task is still incomplete when recap processing exits early, cancel `plansCts` and safely await or otherwise observe the task before returning or propagating the recap failure, while preserving the existing fail-open behavior when recap succeeds but the plans lookup fails. Add coverage where the recap request throws while the plans endpoint remains pending, and verify that the plans request is cancelled before the tool call returns.

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



Remediation recommended

2. Agents cannot classify some open plans ✓ Resolved 🐞 Bug ≡ Correctness
Description
The recap skill's decision tree has no branch for finished: false when completed == total,
total_known and is_complete are both true. The implementation deliberately trusts a
server-supplied finished: false for exactly that combination, so agents following the new
instructions reach none of the four outcomes.
Code

kcap/skills/recap/SKILL.md[R115-118]

+1. `progress.finished` is `true` — the plan is done.
+2. `progress.completed` is less than `progress.total` — the plan is open. What remains is every entry of `tasks` whose status is neither `completed` nor `skipped`; a `list_repo_plans` row has no `tasks`, and gives the first of them as `next_task`.
+3. `is_complete` is `false` — nothing visible remains — possibly nothing visible was declared — but the view is partial; say so and do not call the plan complete.
+4. Otherwise `progress.total_known` is `false` — the session declared documents but never a task list, so completion is unknown. That is not withheld data; do not report it as a partial view.
Relevance

●●● Strong

The decision tree omits an explicit server-reported unfinished state when visible progress appears
complete.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The skill covers true, incomplete visible totals, a partial view, and unknown totals, but not the
all-true visible-total combination with an explicit false result. Projection lines 790-792 prefer
the server field over the fallback calculation, and the unit test explicitly verifies that
finished: false is retained for completed 3 of 3 with a complete, known view.

kcap/skills/recap/SKILL.md[113-124]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[785-803]
test/Capacitor.Cli.Tests.Unit/Commands/McpSessionsServerTests.cs[654-658]

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 plan-classification flow is incomplete when the server authoritatively reports `finished: false` even though the visible totals otherwise look complete.

## Fix Focus Areas
- kcap/skills/recap/SKILL.md[113-124]
- src/Capacitor.Cli/Commands/McpSessionsServer.cs[785-803]
- test/Capacitor.Cli.Tests.Unit/Commands/McpSessionsServerTests.cs[654-658]

## Recommended Fix
Add a final branch stating that a present `finished: false` remains authoritative when none of the diagnostic conditions explains it: report the plan as unfinished and do not infer completion from totals. Preserve the existing fallback formula only for responses where `finished` is absent.

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


3. Agents misread ended sessions ✓ Resolved 🔗 Cross-repo conflict ≡ Correctness
Description
The list_repo_plans description defines stale solely as having no activity for over an hour.
Because kcap-server only marks active sessions stale and always reports false for ended sessions,
agents can mistake an old ended session for recent activity.
Code

src/Capacitor.Cli/Commands/McpSessionsServer.cs[882]

+            "List the declared plans on a repository that you are allowed to see, most recently touched first. Reach for this to find unfinished work: a plan a session left behind when it ended. Each row carries plan_id, documents (kind, path, content_hash, commit_sha — no bodies), progress {completed, total, total_known, finished}, next_task (the first task neither completed nor skipped, or null), sessions, work_item_id, last_touched_at, is_complete and withheld_contributions; read the full task list with get_declared_plans(plan_id). progress.finished is whether the work is done. is_complete is NOT that: it only says nothing was withheld from your view, and a half-done plan usually has is_complete true. A non-zero withheld_contributions means other people's tasks exist that you cannot see, so never call such a plan complete. On sessions, status and stale describe the session as a whole — stale means no activity for over an hour — and only last_touched_at is about this plan: a session stays attached after moving to other work, so an active session is not proof anyone is executing the plan.",
Relevance

●●● Strong

The server’s stale predicate is status-dependent; accepted precedent treats active-session lifecycle
semantics as correctness-critical.

PR-#256

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR presents stale as a pure age test, but the server predicate requires active status before
considering the one-hour threshold and exposes that predicate in repository-plan session rows.

src/Capacitor.Cli/Commands/McpSessionsServer.cs[880-882]
External repo: kurrent-io/kcap-server, src/Capacitor.Server.Core/Sessions/SessionStaleness.cs [3-9]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public/Plans/RepoPlansHandler.cs [42-56]

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 tool description omits that kcap-server's `stale` flag applies only to active sessions; ended sessions remain non-stale regardless of age.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpSessionsServer.cs[880-882]

## Recommended Fix
Describe `stale` as true only for an active session with no activity for over an hour. Explicitly direct agents to use `status` and timestamps when interpreting ended sessions.

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


4. Recap errors stall all later requests ✓ Resolved 🐞 Bug ➹ Performance
Description
HandleSessionSummaryAsync awaits plansTask before checking whether the recap returned an
unsuccessful or unauthorized status. When /recap answers immediately but /plans stalls, the
error response and every later request on the serial stdio loop wait for the secondary lookup's
ten-second deadline.
Code

src/Capacitor.Cli/Commands/McpSessionsServer.cs[R292-294]

+            using var recap = await client.GetAsync(recapUrl);
+            var       body  = await recap.Content.ReadAsStringAsync();
+            var       plans = await plansTask;
Relevance

●●● Strong

Accepted precedent specifically flags optional secondary requests that delay returning successful
primary results.

PR-#480

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The code explicitly identifies the stdio loop as serial and gives the plans lookup a ten-second
deadline, but awaits that lookup at line 294 before either status check at lines 296-301. The main
loop awaits each tool call before reading and responding to subsequent requests, so this ordering
turns a best-effort secondary read into a delay on every recap error.

src/Capacitor.Cli/Commands/McpSessionsServer.cs[288-301]
src/Capacitor.Cli/Commands/McpSessionsServer.cs[105-123]

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

## Issue description
`HandleSessionSummaryAsync` waits for the best-effort plans request before inspecting the recap status, delaying recap errors and blocking the serial MCP request loop.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpSessionsServer.cs[288-304]
- test/Capacitor.Cli.Tests.Integration/McpSessionsServerTests.cs[372-387]

## Recommended Fix
Inspect the recap status immediately after reading its body. If it failed or was unauthorized, cancel the plans lookup, await its completion safely for cleanup, and return the recap error without waiting for the plans timeout; add a test using a stalled plans response.

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


View medium (2)
5. Agents invent hidden plan tasks ✓ Resolved 🔗 Cross-repo conflict ≡ Correctness
Description
The list_repo_plans description equates every non-zero withheld_contributions value with hidden
tasks. When kcap-server withholds only a document, attached session, or work-item link, agents are
incorrectly told that other users contributed tasks they cannot see.
Code

src/Capacitor.Cli/Commands/McpSessionsServer.cs[882]

+            "List the declared plans on a repository that you are allowed to see, most recently touched first. Reach for this to find unfinished work: a plan a session left behind when it ended. Each row carries plan_id, documents (kind, path, content_hash, commit_sha — no bodies), progress {completed, total, total_known, finished}, next_task (the first task neither completed nor skipped, or null), sessions, work_item_id, last_touched_at, is_complete and withheld_contributions; read the full task list with get_declared_plans(plan_id). progress.finished is whether the work is done. is_complete is NOT that: it only says nothing was withheld from your view, and a half-done plan usually has is_complete true. A non-zero withheld_contributions means other people's tasks exist that you cannot see, so never call such a plan complete. On sessions, status and stale describe the session as a whole — stale means no activity for over an hour — and only last_touched_at is about this plan: a session stays attached after moving to other work, so an active session is not proof anyone is executing the plan.",
Relevance

●●● Strong

The description incorrectly infers hidden tasks from a counter also covering documents, sessions,
and links.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR tells agents that the counter specifically proves hidden tasks exist, while kcap-server
increments the same counter for hidden work-item links, sessions, documents, and tasks.

src/Capacitor.Cli/Commands/McpSessionsServer.cs[880-882]
External repo: kurrent-io/kcap-server, src/Capacitor.Server.Services/ReadModels/Plans/PlanReads.cs [228-237]
External repo: kurrent-io/kcap-server, src/Capacitor.Server.Services/ReadModels/Plans/PlanReads.cs [244-258]
External repo: kurrent-io/kcap-server, src/Capacitor.Server.Services/ReadModels/Plans/PlanReads.cs [260-276]

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 `list_repo_plans` tool description says `withheld_contributions` exclusively counts hidden tasks, but kcap-server also counts hidden documents, attached sessions, and work-item links.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpSessionsServer.cs[880-882]

## Recommended Fix
Change the description to say that a non-zero value means one or more contributions are withheld, potentially including documents, tasks, sessions, or the work-item link. Keep the instruction not to declare the plan complete from that partial view.

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


6. Some unfinished plans stay undiscovered ✓ Resolved 🐞 Bug ≡ Correctness
Description
The new resume instructions direct agents with no session ID to call list_repo_plans without
specifying a state, although that tool's default open state only includes plans with an unfinished
task visible to the caller. A plan whose visible tasks are completed but whose withheld contribution
contains unfinished work is omitted from this prescribed discovery flow, despite the same
instructions saying a partial view must not be considered complete.
Code

kcap/skills/plans/SKILL.md[45]

+1. **Find it.** `list_repo_plans` lists this repository's open plans. Read each row's `sessions` together: a session that is `active`, not `stale`, and whose `last_touched_at` is recent may still be executing the plan — **ask the user before adopting it**. An active session whose `last_touched_at` is old has most likely moved to other work; a session stays attached to every plan it ever touched, so that alone is no reason to hold back.
Relevance

●●● Strong

The default open listing can omit partially hidden unfinished plans; discovery instructions need an
all-state fallback.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The tool description added in this PR defines the default open filter in terms of tasks the caller
can see, while also stating that withheld contributions can contain other users' work and prohibit
treating the plan as complete. The new skills prescribe the default listing as the starting point
for finding plans, without an all-state fallback.

src/Capacitor.Cli/Commands/McpSessionsServer.cs[881-889]
kcap/skills/plans/SKILL.md[43-49]
kcap/skills/recap/SKILL.md[108-120]

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 resume flow tells agents to find unfinished plans with the default `list_repo_plans` call. That default is `state: open`, which is defined using only visible unfinished tasks, so it excludes partially visible plans whose visible tasks are done but whose withheld tasks are still open.

## Fix Focus Areas
- kcap/skills/plans/SKILL.md[45-45]
- kcap/skills/recap/SKILL.md[108-120]

## Recommended Fix
Change the no-session-id discovery instructions to call `list_repo_plans(state: "all")`, or explicitly follow the default open listing with an all-state listing and inspect any rows where `is_complete` is false. Explain that partial plans may be absent from the default open result because its open predicate is based on visible tasks.

ⓘ 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 (branch: capacitor/agent-74b7aef0417848, sha: 468d3057)
Review mode: 🧠 Deep: This is a substantial behavioral MCP/API change spanning routing, URL validation, fail-open concurrency, JSON projection, tool contracts, and skills, with many independent paths where a redundant review could catch subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can choose which labels appear on a finding, and whether they show icons or text

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli/Commands/McpSessionsServer.cs Outdated
Comment thread kcap/skills/recap/SKILL.md Outdated
Comment thread src/Capacitor.Cli/Commands/McpSessionsServer.cs Outdated
Comment thread kcap/skills/plans/SKILL.md Outdated
Comment thread src/Capacitor.Cli/Commands/McpSessionsServer.cs Outdated
Comment thread src/Capacitor.Cli/Commands/McpSessionsServer.cs Outdated
A failed or unauthorized recap must not wait out the plans lookup's 10 s bound, and a dot segment in session_id must not escape the route.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@alexeyzimarev
alexeyzimarev merged commit 4dbdc73 into main Sep 24, 2026
14 of 15 checks passed
@alexeyzimarev
alexeyzimarev deleted the alexeyzimarev/ai-3036-plan-ledger-recall-repo-level-open-plans-and-session-plans branch September 24, 2026 12:14
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.

Sessions MCP: find and read declared plans, and point a session summary at them

1 participant