Skip to content

Review saved execution traces in Release reviews - #2219

Open
sidneyswift wants to merge 1 commit into
mainfrom
claude/ctx-2146-execution-trace
Open

sidneyswift wants to merge 1 commit into
mainfrom
claude/ctx-2146-execution-trace

Conversation

@sidneyswift

@sidneyswift sidneyswift commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Makes saved execution traces reviewable from the shipped /releases reviewer UI using only the already-deployed, read-only list_executions and read_execution operations (no api or database change). A new "Execution traces" panel under the current case lists the request's saved executions (policy version, created time, recorded/planned node counts) and opens one as a node table that joins the immutable plan with recorded outcomes and claims. Review state is the outcome status (saved/reused/failed/blocked), else unknown (claimed, needs reconciliation) for a claim without an outcome, else not_started, so uncertainty is never rendered as success or failure. Plan states are separated into template (not_implemented), implemented (ready_for_dispatch / reuse_candidate) and blocked by policy; dependencies, block reasons, failure stage, reasons, evidence result IDs and claim/outcome timestamps are shown; cost is always unknown (never zero) and each row names what was not recorded (prompts, cost, outcome). The hook mirrors useCompanyAssessment (generation counter, shared useReleaseCaseRequest with workspace organization_id on every call, 401 → sign-in message) and never retries or dispatches.

Refs #2146 (child of epic #2116).

Merge sequencing

docs → database → api → app:

Verification

  • Ran: pnpm exec vitest run lib/releases/__tests__/buildExecutionNodeRows.test.ts components/Releases/__tests__/ReleaseExecutionTrace.test.tsx → 2 files, 7 tests passed, 0 failed, 0 skipped.
  • Ran: pnpm exec vitest run components/Releases hooks lib/releases → 59 files, 187 tests passed, 0 failed (baseline on origin/main before this change: 57 files, 180 passed).
  • Ran: pnpm exec tsc --noEmit → no errors in changed files. The only reported error is pre-existing and unrelated: components/VercelChat/tools/SpotifyDeepResearchResult.tsx(5,25) imports a .png and needs the gitignored, generated next-env.d.ts (absent in a fresh worktree); with that file generated, tsc reports zero errors.
  • Ran: pnpm exec eslint <9 changed files> → clean; pnpm exec prettier --check <9 changed files> → all files use Prettier code style.
  • Ran: grep -c 'read_execution' components/Releases/ReleaseExecutionTrace.tsx hooks/useExecutionTrace.ts → 1 and 1.
  • Red → green: both new test files failed before implementation (Cannot find module '../buildExecutionNodeRows' and '../ReleaseExecutionTrace'); after the first implementation 6/7 passed and ReleaseExecutionTrace.test.tsx failed on findByText("unknown (claimed, needs reconciliation)") matching both the table cell and the legend; the test was scoped to the node table via within(table) and all 7 pass.
  • Not verified: hosted deployment, live providers, production database, hosted UI display of a real trace (no real execution was read through the deployed /api/context proxy), MCP transport. State reached: implemented + fixture-tested.

Out of scope / known gaps

  • Per-node cost, duration and prompts are not recorded by the execution schema; the UI states this explicitly instead of inferring values.
  • Connected, fixture-tested and live-verified status per node is not derivable from a trace; the panel says it lives in implementation tickets. No links to schema/implementation tickets yet.
  • No retry, reconciliation or human-review-checkpoint actions; reads only. Evidence permissions rely on the server's workspace authorization and owner-scoped RPCs.
  • The private React Flow inspector and Business reference docs are out of scope per the ticket's ownership statement.
  • Added components/Releases/ReleaseExecutionNodes.tsx (table + legend + footer) beyond the plan's file list to keep one component per file.

🤖 Generated with Claude Code


Summary by cubic

Makes saved execution runs reviewable in Release reviews for the first time. A new "Execution traces" panel under the current case lists the request's saved executions and opens one as a node table joining the immutable plan with recorded outcomes and claims, using only the already-deployed read-only list_executions and read_execution operations. Opening a trace never retries work, dispatches a provider, or spends credits.

  • Review state is the recorded outcome status (saved/reused/failed/blocked), else unknown (claimed, needs reconciliation) for a claim with no outcome, else not_started, so uncertainty is never rendered as success or failure.
  • Plan states map to template (not_implemented), implemented (ready_for_dispatch / reuse_candidate), and blocked by policy; dependencies, block reasons, failure stage, reasons, evidence result IDs, and claim/outcome timestamps are shown.
  • Cost is always reported as unknown, never zero, and each row names what was not recorded: prompts, cost, and outcome.
  • The hook follows useCompanyAssessment behavior and shows a sign-in message on 401.
  • No API or database changes are needed; both operations are already merged and deployed, and edits to existing app files are limited to an import, a mount, and two typed actions.

Written for commit cab0135. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • Added an execution trace panel to release cases, where reviewers can view saved executions and their status.
    • Execution details show modules, implementation and review states, dependencies, timing, costs, and available evidence or failure information.
    • Added explanatory status guidance and notices when trace information is unavailable.

Reviewers could see evidence versions, gaps and review receipts on
/releases but nothing about the runs that produced them: no entry,
retry, failure, claim or node state was reviewable in the product UI,
even though list_executions and read_execution are merged and deployed.

Add an "Execution traces" panel under the current case that lists the
request's saved executions and opens one as a node table joining the
immutable plan with recorded outcomes and claims. The review state is
the outcome status, else "unknown (claimed, needs reconciliation)" for a
claim without an outcome, else not_started, so uncertainty is never
shown as success or failure. Plan states map to template, implemented
and blocked by policy. Cost is reported as unknown, never zero, and the
rows name what was not recorded (prompts, cost, outcome). The hook only
reads through the shared operations and never retries or dispatches.

Refs #2146

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
app Ready Ready Preview Oct 10, 2026 8:29pm UTC

Request Review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 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-10-10T20:29:13.089118Z cab0135 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.

@coderabbitai

coderabbitai Bot commented Oct 10, 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: recoupable/app/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f0edba38-aad7-4f02-8e36-8b2e58001548

📥 Commits

Reviewing files that changed from the base of the PR and between 025342d and cab0135.


⛔ Files ignored due to path filters (2)
  • components/Releases/__tests__/ReleaseExecutionTrace.test.tsx is excluded by !**/*.test.* and included by components/**
  • lib/releases/__tests__/buildExecutionNodeRows.test.ts is excluded by !**/*.test.* and included by lib/**

📒 Files selected for processing (7)
  • components/Releases/ReleaseCasesPage.tsx
  • components/Releases/ReleaseExecutionNodes.tsx
  • components/Releases/ReleaseExecutionTrace.tsx
  • hooks/useExecutionTrace.ts
  • lib/releases/buildExecutionNodeRows.ts
  • lib/releases/executionTypes.ts
  • lib/releases/responseTypes.ts

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



📝 Walkthrough

Walkthrough

The release case page now includes an execution trace panel. The panel loads saved executions, opens a selected trace, and displays execution metadata and node details.

Changes

Release execution trace

Layer / File(s) Summary
Execution data and row mapping
lib/releases/executionTypes.ts, lib/releases/responseTypes.ts, lib/releases/buildExecutionNodeRows.ts
New types describe plans, outcomes, claims, summaries, traces, and node rows. Response types include execution-list and trace-read results. The row builder joins plan nodes with outcomes and claims in plan order.
Trace loading and request lifecycle
hooks/useExecutionTrace.ts
The hook lists executions and opens a selected trace using the supplied request and organization context. It clears the trace on failure and prevents stale requests from updating state.
Trace view and release case integration
components/Releases/ReleaseCasesPage.tsx, components/Releases/ReleaseExecutionTrace.tsx, components/Releases/ReleaseExecutionNodes.tsx
The release case page renders the trace panel for the current case. The panel displays execution metadata and selected trace rows. The node table shows implementation, review state, dependencies, timestamps, cost, and available outcome details.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseCasesPage
  participant ReleaseExecutionTrace
  participant useExecutionTrace
  participant ReleaseExecutionNodes
  ReleaseCasesPage->>ReleaseExecutionTrace: Pass request and organization context
  ReleaseExecutionTrace->>useExecutionTrace: List executions or open a trace
  useExecutionTrace-->>ReleaseExecutionTrace: Return execution or trace state
  ReleaseExecutionTrace->>ReleaseExecutionNodes: Pass selected trace rows
Loading

Merge Risk: ⚪ Minimal · up to cab01

The trace panel is mergeable after normal checks. No concrete issue remains that would prevent reviewers from loading or reading saved traces.

Pre-merge checks | Passed 2 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Solid & Clean Code Warning The pull request introduces several oversized, multi-purpose functions. ReleaseExecutionNodes spans lines 28–126 and renders the node table, state legend, and trace disclaimer. `ReleaseExecutionTrac… Split the UI into focused components for the execution list, node table, state legend, and trace notice. Extract row-state, missing-data, and row-projection helpers from buildExecutionNodeRows. Separate list and open operations from the h…
✅ Passed checks (2 passed)
Check name Status Explanation
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.

Full details: Solid & Clean Code

Explanation

The pull request introduces several oversized, multi-purpose functions. ReleaseExecutionNodes spans lines 28–126 and renders the node table, state legend, and trace disclaimer. ReleaseExecutionTrace spans lines 16–90 and handles loading, execution-list rendering, trace rendering, and notices. useExecutionTrace spans lines 16–77 and combines lifecycle invalidation, request orchestration, state updates, and error mapping. buildExecutionNodeRows spans lines 20–67 and combines joins, review-state calculation, presentation labels, and missing-data messages. The repeated review label also appears in both ReleaseExecutionNodes.tsx:21 and buildExecutionNodeRows.ts:52. These new functions exceed the stated 20-line guideline and mix responsibilities.

Resolution

Split the UI into focused components for the execution list, node table, state legend, and trace notice. Extract row-state, missing-data, and row-projection helpers from buildExecutionNodeRows. Separate list and open operations from the hook while retaining one small shared request/error wrapper. Define shared constants for repeated review labels and missing-data messages.


  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • 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

A saved trace unfolds in rows
Plan and outcome find their place
Claims mark time, or leave it blank
Notices speak when requests fail
Release cases show the trail
Quietly, each state comes into view

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

@cubic-dev-ai cubic-dev-ai 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.

6 issues found across 9 files

Confidence score: 4/5

  • ReleaseCasesPage.tsx and ReleaseExecutionNodes.tsx now coordinate several distinct UI responsibilities, which makes these components harder to maintain. Split out focused components where that simplifies ownership.
  • ReleaseExecutionTrace.tsx does not announce loaded results or an opened node table to screen-reader users. Add a persistent polite status message for those actions.
  • ReleaseExecutionNodes.tsx can show saved, reused, failed, and blocked review states, but the legend does not explain them. Add those states to the legend so users can interpret the column.
  • ReleaseExecutionTrace.test.tsx does not assert that an unclaimed, unrecorded node renders as not_started. Add that assertion to catch regressions in this state.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="components/Releases/ReleaseCasesPage.tsx">

<violation number="1" location="components/Releases/ReleaseCasesPage.tsx:98">
P2: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**

`ReleaseCasesPage.tsx` is now 109 lines and coordinates another panel alongside the list, intake, details, and assessment. Extract the current-case panel composition into a focused component so this page stays under the rule’s 100-line limit.</violation>
</file>

<file name="components/Releases/ReleaseExecutionNodes.tsx">

<violation number="1" location="components/Releases/ReleaseExecutionNodes.tsx:10">
P3: The legend explains only `template`, `implemented`, `blocked by policy`, `unknown (claimed, needs reconciliation)` and `not_started`, but the Review state column can also render `saved`, `reused`, `failed` and `blocked`, which are neither in the legend nor qualified in the prose below it. Add legend entries for the four outcome statuses so reviewers can tell recorded outcomes apart from policy states.</violation>

<violation number="2" location="components/Releases/ReleaseExecutionNodes.tsx:28">
P2: Custom agent: **Code Structure and Size Limits for Readability and Single Responsibility**

`ReleaseExecutionNodes.tsx` is 126 lines and combines the node table, state legend, and trace disclaimer, exceeding Rule 1’s 100-line limit. Split the legend and/or footer into focused components so this file stays under the limit.</violation>
</file>

<file name="lib/releases/__tests__/buildExecutionNodeRows.test.ts">

<violation number="1" location="lib/releases/__tests__/buildExecutionNodeRows.test.ts:1">
P2: Custom agent: **Enforce Clear Code Style and Maintainability Practices**

This new test file is 174 lines, over the 100-line limit the style rules set for all files. The bulk is the inline `trace` fixture and `node`/`row` helpers, not assertions. Extract the fixture into a sibling fixture module (the repo already does this with `streamHistoryFixture.ts`/`streamSeriesFixture.ts`) and import it here, keeping the test file under 100 lines.</violation>
</file>

<file name="components/Releases/__tests__/ReleaseExecutionTrace.test.tsx">

<violation number="1" location="components/Releases/__tests__/ReleaseExecutionTrace.test.tsx:125">
P3: The fixture includes an unclaimed, unrecorded node, but this panel test never asserts its rendered `not_started` state. Assert that label so the UI test catches regressions that stop distinguishing unstarted nodes from other states.</violation>
</file>

<file name="components/Releases/ReleaseExecutionTrace.tsx">

<violation number="1" location="components/Releases/ReleaseExecutionTrace.tsx:45">
P2: The non-empty list and opened node table appear without a live announcement, so screen-reader users receive no result announcement after either action. Add a persistent polite status message for loaded results.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

organizationId={selectedOrgId}
getAccessToken={getAccessToken}
/>
<ReleaseExecutionTrace

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: Custom agent: Code Structure and Size Limits for Readability and Single Responsibility

ReleaseCasesPage.tsx is now 109 lines and coordinates another panel alongside the list, intake, details, and assessment. Extract the current-case panel composition into a focused component so this page stays under the rule’s 100-line limit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseCasesPage.tsx, line 98:

<comment>`ReleaseCasesPage.tsx` is now 109 lines and coordinates another panel alongside the list, intake, details, and assessment. Extract the current-case panel composition into a focused component so this page stays under the rule’s 100-line limit.</comment>

<file context>
@@ -94,6 +95,12 @@ export default function ReleaseCasesPage() {
               organizationId={selectedOrgId}
               getAccessToken={getAccessToken}
             />
+            <ReleaseExecutionTrace
+              key={"trace" + currentKey}
+              requestId={current.request_id}
</file context>

@@ -0,0 +1,126 @@
import {

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: Custom agent: Code Structure and Size Limits for Readability and Single Responsibility

ReleaseExecutionNodes.tsx is 126 lines and combines the node table, state legend, and trace disclaimer, exceeding Rule 1’s 100-line limit. Split the legend and/or footer into focused components so this file stays under the limit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseExecutionNodes.tsx, line 28:

<comment>`ReleaseExecutionNodes.tsx` is 126 lines and combines the node table, state legend, and trace disclaimer, exceeding Rule 1’s 100-line limit. Split the legend and/or footer into focused components so this file stays under the limit.</comment>

<file context>
@@ -0,0 +1,126 @@
+];
+const formatTime = (value?: string) =>
+  value ? new Date(value).toLocaleString() : "not recorded";
+export default function ReleaseExecutionNodes({
+  rows,
+}: {
</file context>

@@ -0,0 +1,174 @@
import { expect, it } from "vitest";

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: Custom agent: Enforce Clear Code Style and Maintainability Practices

This new test file is 174 lines, over the 100-line limit the style rules set for all files. The bulk is the inline trace fixture and node/row helpers, not assertions. Extract the fixture into a sibling fixture module (the repo already does this with streamHistoryFixture.ts/streamSeriesFixture.ts) and import it here, keeping the test file under 100 lines.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At lib/releases/__tests__/buildExecutionNodeRows.test.ts, line 1:

<comment>This new test file is 174 lines, over the 100-line limit the style rules set for all files. The bulk is the inline `trace` fixture and `node`/`row` helpers, not assertions. Extract the fixture into a sibling fixture module (the repo already does this with `streamHistoryFixture.ts`/`streamSeriesFixture.ts`) and import it here, keeping the test file under 100 lines.</comment>

<file context>
@@ -0,0 +1,174 @@
+import { expect, it } from "vitest";
+import { buildExecutionNodeRows } from "../buildExecutionNodeRows";
+import type { ExecutionTrace, PlanNode } from "../executionTypes";
</file context>

No recorded executions for this request.
</p>
)}
{!!traces.executions?.length && (

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: The non-empty list and opened node table appear without a live announcement, so screen-reader users receive no result announcement after either action. Add a persistent polite status message for loaded results.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseExecutionTrace.tsx, line 45:

<comment>The non-empty list and opened node table appear without a live announcement, so screen-reader users receive no result announcement after either action. Add a persistent polite status message for loaded results.</comment>

<file context>
@@ -0,0 +1,90 @@
+          No recorded executions for this request.
+        </p>
+      )}
+      {!!traces.executions?.length && (
+        <ul className="space-y-2" aria-label="Recorded executions">
+          {traces.executions.map((execution) => (
</file context>

expect(table.getByText("collection_not_permitted")).toBeTruthy();
expect(table.getByText(resultId)).toBeTruthy();
expect(table.getByText("template")).toBeTruthy();
expect(table.getByText("blocked by policy")).toBeTruthy();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The fixture includes an unclaimed, unrecorded node, but this panel test never asserts its rendered not_started state. Assert that label so the UI test catches regressions that stop distinguishing unstarted nodes from other states.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/__tests__/ReleaseExecutionTrace.test.tsx, line 125:

<comment>The fixture includes an unclaimed, unrecorded node, but this panel test never asserts its rendered `not_started` state. Assert that label so the UI test catches regressions that stop distinguishing unstarted nodes from other states.</comment>

<file context>
@@ -0,0 +1,176 @@
+  expect(table.getByText("collection_not_permitted")).toBeTruthy();
+  expect(table.getByText(resultId)).toBeTruthy();
+  expect(table.getByText("template")).toBeTruthy();
+  expect(table.getByText("blocked by policy")).toBeTruthy();
+  expect(table.getAllByText("implemented")).toHaveLength(2);
+  expect(table.getAllByText("unknown")).toHaveLength(4);
</file context>

TableRow,
} from "@/components/ui/table";
import type { ExecutionNodeRow } from "@/lib/releases/executionTypes";
const LEGEND: ReadonlyArray<readonly [string, string]> = [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The legend explains only template, implemented, blocked by policy, unknown (claimed, needs reconciliation) and not_started, but the Review state column can also render saved, reused, failed and blocked, which are neither in the legend nor qualified in the prose below it. Add legend entries for the four outcome statuses so reviewers can tell recorded outcomes apart from policy states.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At components/Releases/ReleaseExecutionNodes.tsx, line 10:

<comment>The legend explains only `template`, `implemented`, `blocked by policy`, `unknown (claimed, needs reconciliation)` and `not_started`, but the Review state column can also render `saved`, `reused`, `failed` and `blocked`, which are neither in the legend nor qualified in the prose below it. Add legend entries for the four outcome statuses so reviewers can tell recorded outcomes apart from policy states.</comment>

<file context>
@@ -0,0 +1,126 @@
+  TableRow,
+} from "@/components/ui/table";
+import type { ExecutionNodeRow } from "@/lib/releases/executionTypes";
+const LEGEND: ReadonlyArray<readonly [string, string]> = [
+  [
+    "template",
</file context>

This branch was successfully deployed

1 active deployment
Preview – app — cab01355 Deployed Oct 10, 2026 by vercel[bot]
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