Skip to content

feat(cli): surface the autonomous goal in the TUI - #3025

Merged
Astro-Han merged 3 commits into
apache:mainfrom
me2seeks:feat/cli-goal-visibility
Aug 19, 2026
Merged

feat(cli): surface the autonomous goal in the TUI#3025
Astro-Han merged 3 commits into
apache:mainfrom
me2seeks:feat/cli-goal-visibility

Conversation

@me2seeks

@me2seeksme2seeks commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

An armed goal burns tokens between prompts, but the TUI showed nothing: goal continuation turns rendered as plain user prompts, the status line had no goal segment, and the only way to inspect the loop was spending a model turn on GoalStatus. This PR surfaces the autonomous goal in the TUI using the same authoritative push channel the desktop observer already diffs.

  • Status line shows a live goal (active/waiting/paused) with the iteration counter and elapsed wall-clock (e.g. goal 3/50 12m); terminal goals stay hidden, matching the desktop chip.
  • Goal-origin turns render with a Goal continuation (autonomous) provenance header instead of as user prompts, folded from stored messages so replay/reconnect can never duplicate or diverge.
  • /goal prints condition, status, iterations, elapsed, tokens vs budget, and the evaluator's last note without burning a turn — and works while the loop is busy.
  • Transport: goal state rides the session subscription's continuity snapshot (GoalProjection), so every transition (set, evaluator settle, abort auto-pause, waiting wake, terminal verdict, cross-client control) reaches the TUI as it happens. No polling, no stale window, no new RPC.

Ref #3022

Review process

Two independent read-only review passes (first-principles + Occam's razor) over the diff. Findings addressed in this branch:

  • major/goal typed during a running turn was steered into the model as literal text; read-only status commands now answer locally mid-turn (the feature's primary use case), with a regression test asserting steer is not called.
  • minor — goal-change listener payload is now defensively cloned on both the canonical-replacement and per-frame paths.
  • nit/goal summary collapses embedded whitespace in condition/evaluator note, and a cleared goal is labeled Cleared goal: instead of presenting its condition as armed.

Deferred (out of scope): TUI goal control (pause/resume/clear) is tracked in #3023; GoalManager.remove() not firing the invalidation pipeline is pre-existing runtime behavior only reachable on session retirement.

Test plan

  • packages/cli: 272 tests pass (node --test), including new coverage:
    • pi-goal.test.ts — status-line text, elapsed formatting, exhaustive status labels, summary whitespace/cleared handling
    • pi-transcript.test.ts — status-line goal segment rendering + goal-continuation provenance header
    • pi-tui-runner.test.ts/goal summary end-to-end, /goal mid-turn local answer (no steer), host-pushed pause reaching the status line
    • runtime-host-session-driver.test.tsgetGoal/subscribeGoalChanges wiring, no-RPC, no-duplicate-notify
  • biome check clean; tsc --noEmit clean for @maka/cli.

🤖 Generated by Maka

Visual evidence

The same stored goal-origin message before and after this PR, followed by the local /goal summary and live status-line projection.

BeforeAfter
Goal continuation before TUI goal visibilityGoal continuation provenance and goal status after

@me2seeks
me2seeksforce-pushed the feat/cli-goal-visibility branch 2 times, most recently from 7ae8d0d to 5739ed0CompareAugust 14, 2026 23:40
@me2seeks
me2seeksforce-pushed the feat/cli-goal-visibility branch from 5739ed0 to 7e94b22CompareAugust 17, 2026 15:13
@coderabbitai

coderabbitaiBot commented Aug 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@me2seeks, you've reached your PR review limit, so we couldn't start this review.

Next review available in:32 minutes

Limit details: You’ve used all 3 included reviews currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b25ad0a7-d4a4-4a6b-9db3-a5eb39b2facf

📥 Commits

Reviewing files that changed from the base of the PR and between 62556ab and 07b4cbd.

📒 Files selected for processing (13)
  • packages/cli/src/__tests__/pi-goal.test.ts
  • packages/cli/src/__tests__/pi-transcript.test.ts
  • packages/cli/src/__tests__/pi-tui-runner.test.ts
  • packages/cli/src/__tests__/runtime-host-session-driver.test.ts
  • packages/cli/src/pi-goal.ts
  • packages/cli/src/pi-transcript-format.ts
  • packages/cli/src/pi-transcript.ts
  • packages/cli/src/pi-tui-runner.ts
  • packages/cli/src/runtime-host-session-channel.ts
  • packages/cli/src/runtime-host-session-driver.ts
  • packages/cli/src/session-driver.ts
  • packages/cli/src/tui-primary-guidance.ts
  • packages/core/src/slash-command-catalog.ts

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

@me2seeks
me2seeks marked this pull request as ready for review August 17, 2026 17:05
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Surface autonomous goal state in the CLI TUI (status line, transcript, /goal)

✨ Enhancement🐞 Bug fix🧪 Tests🕐 40+ Minutes

Grey Divider

AI Description

• Show live goal state in the TUI status line using host-pushed projection updates (no polling/RPC).
• Render goal-origin prompts with an autonomous provenance header instead of as user prompts.
• Add a read-only /goal command that prints goal details locally, even mid-turn.
Diagram

graph TD
A["Runtime Host subscription"] --> B["Session channel"] --> C["Session driver"] --> D["TUI runner"] --> E["Transcript renderer"] --> F["Goal display helpers"]
C --> D
E --> D
E --> G["Goal provenance block"]
subgraph Legend
direction LR
_ext{{External push}} ~~~ _svc([Component/service]) ~~~ _mod["Module"]
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add a dedicated goal RPC (e.g. goal.query + goal.subscribe)
  • ➕ Clear separation of concerns and explicit API for goal state consumers
  • ➕ Potentially smaller coupling to the generic session projection snapshot
  • ➖ Introduces new network calls and staleness windows unless carefully streamed
  • ➖ Duplicates infrastructure already present in the projection stream (desktop already diffs it)
  • ➖ More surface area to maintain and test (new ops, permissions, versioning)
2. Poll goal state from the TUI at an interval
  • ➕ Simple to implement without changing channel/driver interfaces
  • ➖ Adds periodic work and still risks staleness between polls
  • ➖ Harder to reason about correctness during rapid transitions (pause/resume/settle)
  • ➖ Contradicts the repo’s existing push-based projection model
3. Maintain a cached goal copy inside the TUI runner
  • ➕ Can reduce repeated reads and isolate UI from driver details
  • ➖ Creates a second source of truth and drift risk (replay/reconnect duplication)
  • ➖ Requires more invalidation logic and careful sequencing with subscription events

Recommendation: The chosen approach (goal state riding the authoritative session projection snapshot, surfaced via driver getGoal()/subscribeGoalChanges()) is the best fit: it avoids new RPCs and polling, matches the desktop observer’s source of truth, and ensures immediate cross-client updates. Keeping the TUI stateless (reading the driver on demand and only subscribing to trigger re-renders) minimizes drift and makes reconnect/replay correctness easier to maintain.

Files changed (12) +760 / -9

Enhancement (6) +299 / -9
pi-goal.tsIntroduce shared goal display helpers for status line and '/goal'+124/-0

Introduce shared goal display helpers for status line and '/goal'

• Adds pure formatting utilities for goal visibility in the TUI: live-status classification, labels, elapsed computation (with paused/achieved freeze semantics), compact elapsed formatting, status-line segment formatting, and multi-line '/goal' summaries including token budget/spend and evaluator notes with whitespace normalization.

packages/cli/src/pi-goal.ts

pi-transcript.tsRender goal state in status line and goal-origin turns with provenance+52/-9

Render goal state in status line and goal-origin turns with provenance

• Extends transcript entry types with 'goal_continuation' and maps stored user messages with origin.kind==='goal' to that entry type. Adds status-line rendering of live goals (accent/paused warning coloring) using the new goal helpers, and refactors provenance rendering into a shared helper used by both legacy automation and goal continuation blocks.

packages/cli/src/pi-transcript.ts

pi-tui-runner.tsAdd '/goal' command and re-render on pushed goal changes+59/-0

Add '/goal' command and re-render on pushed goal changes

• Subscribes to driver goal-change events to trigger re-render, and plumbs the live goal projection into transcript metadata on each render. Adds a '/goal' slash command that prints a local summary (no turn burn) and routes '/goal' to local handling even while a turn is running to prevent accidental steering into the model.

packages/cli/src/pi-tui-runner.ts

runtime-host-session-channel.tsDetect goal projection changes while folding subscription frames+29/-0

Detect goal projection changes while folding subscription frames

• Adds an 'onGoalChanged' callback and emits it when the folded snapshot’s goal projection changes, both for canonical snapshot replacement and incremental frame acceptance. Implements dedupe via goalId+revision and defensively clones the payload so listeners cannot mutate the live snapshot.

packages/cli/src/runtime-host-session-channel.ts

runtime-host-session-driver.tsExpose getGoal/subscribeGoalChanges from runtime-host session driver+22/-0

Expose getGoal/subscribeGoalChanges from runtime-host session driver

• Adds goal read + subscription APIs to the runtime-host session driver, backed by the session channel’s folded continuity snapshot. Publishes initial goal state on channel adoption and forwards push updates (guarded by session generation) to listeners.

packages/cli/src/runtime-host-session-driver.ts

session-driver.tsExtend session driver interface with optional goal APIs+13/-0

Extend session driver interface with optional goal APIs

• Introduces optional 'getGoal()' and 'subscribeGoalChanges()' hooks so goal UI can be enabled when the runtime provides an authoritative goal projection source, while keeping compatibility for drivers without goal support.

packages/cli/src/session-driver.ts

Refactor (1) +6 / -0
pi-transcript-format.tsMove token-count formatting to shared transcript formatter+6/-0

Move token-count formatting to shared transcript formatter

• Adds 'formatTokenCount()' to the shared formatting module so goal summaries and other UI segments use the same token compacting behavior.

packages/cli/src/pi-transcript-format.ts

Tests (4) +454 / -0
pi-goal.test.tsAdd unit tests for goal formatting helpers+129/-0

Add unit tests for goal formatting helpers

• Introduces coverage for live/terminal status classification, elapsed-time semantics, compact elapsed formatting, status-line text formatting, and '/goal' summary formatting (including whitespace collapsing and cleared-goal labeling). Also asserts token formatting behavior used across goal UIs.

packages/cli/src/tests/pi-goal.test.ts

pi-transcript.test.tsTest goal provenance rendering and status-line goal segment+60/-0

Test goal provenance rendering and status-line goal segment

• Adds transcript coverage ensuring goal-origin user messages are rendered as autonomous goal continuation entries with a provenance header. Adds status-line tests verifying live goals render and terminal/absent goals do not.

packages/cli/src/tests/pi-transcript.test.ts

pi-tui-runner.test.tsAdd end-to-end '/goal' and goal push-update tests+160/-0

Add end-to-end '/goal' and goal push-update tests

• Adds an integration-style suite for '/goal' output, confirms the status line shows goal indicators on startup, and verifies host-pushed goal transitions update UI without user action. Includes a regression test ensuring '/goal' mid-turn is handled locally (not steered into the model) and tests no-goal/invalid-subcommand behavior.

packages/cli/src/tests/pi-tui-runner.test.ts

runtime-host-session-driver.test.tsTest goal exposure via continuity snapshot and deduped notifications+105/-0

Test goal exposure via continuity snapshot and deduped notifications

• Adds tests that the runtime-host driver reads goal state from the pushed continuity snapshot without issuing a goal RPC, notifies listeners on goal revision changes, suppresses duplicate notifications when unchanged, and clears goal state/listeners on session reset.

packages/cli/src/tests/runtime-host-session-driver.test.ts

Other (1) +1 / -0
slash-command-catalog.tsRegister '/goal' as a TUI slash command+1/-0

Register '/goal' as a TUI slash command

• Adds the 'goal' command to the slash command catalog for the TUI surface with a required session.

packages/core/src/slash-command-catalog.ts

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (5)📘 Rule violations (0)📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Channel swaps duplicate updates 🐞 Bug➹ Performance
Description
Fix now: #replaceChannel notifies goal listeners on every same-session channel reattachment even
when goalId and revision are unchanged, producing duplicate callbacks and redundant TUI renders.
This bypasses the deduplication used by projection-frame updates and contradicts the PR's
no-duplicate-notify behavior.
Code

packages/cli/src/runtime-host-session-driver.ts[R746-747]

+ const goal = next?.snapshot.goal ?? null;+ for (const listener of this.#goalListeners) listener(goal);
Relevance

●●● Strong

PR explicitly promises no duplicate notifications, and unconditional channel-adoption callbacks
directly violate that tested behavior.

PR-#1661

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Started-turn reattachment replaces a channel within the same session, while the replacement path
broadcasts unconditionally. The session channel already treats equal goalId/revision projections
as unchanged, so the driver path can emit a duplicate that frame processing would suppress.

packages/cli/src/runtime-host-session-driver.ts[743-748]
packages/cli/src/runtime-host-session-driver.ts[843-900]
packages/cli/src/runtime-host-session-channel.ts[619-627]
packages/cli/src/session-driver.ts[121-125]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution
## Issue description
`#replaceChannel` publishes the replacement channel's goal unconditionally, so same-session reattachments can notify listeners even when the effective goal projection has not changed.
## Issue Context
Reuse the existing goal identity-plus-revision comparison semantics. Preserve notifications for genuine attached-session changes and effective goal changes; no new state, configuration, or public surface is needed.
## Fix Focus Areas
- packages/cli/src/runtime-host-session-driver.ts[743-748]
- packages/cli/src/runtime-host-session-channel.ts[619-627]
- packages/cli/src/__tests__/runtime-host-session-driver.test.ts[69-150]

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


2. Adoption leaks mutable goal 🐞 Bug☼ Reliability
Description
Fix now: #replaceChannel passes the channel snapshot's goal object directly to listeners, so a
mutating listener can alter the authoritative object returned by later getGoal() calls. Both
existing channel notification paths clone their payloads specifically to prevent this corruption,
but the new adoption path omits that safeguard.
Code

packages/cli/src/runtime-host-session-driver.ts[R746-747]

+ const goal = next?.snapshot.goal ?? null;+ for (const listener of this.#goalListeners) listener(goal);
Relevance

●●● Strong

Defensive cloning of listener payloads is an established accepted safeguard against mutation
corrupting authoritative state.

PR-#1661
PR-#3007

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
getGoal() reads the nested object held by #channel.snapshot, and #replaceChannel forwards that
same object. In contrast, both channel-originated goal callbacks use structuredClone, with an
explicit comment that this prevents listeners from corrupting the live snapshot.

packages/cli/src/runtime-host-session-driver.ts[625-634]
packages/cli/src/runtime-host-session-driver.ts[743-748]
packages/cli/src/runtime-host-session-channel.ts[364-369]
packages/cli/src/runtime-host-session-channel.ts[487-491]

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 driver-level channel replacement callback exposes the channel snapshot's goal object by reference, allowing listener mutation to corrupt subsequent goal reads.
## Issue Context
Apply the same defensive-copy behavior already used by the channel's canonical-replacement and per-frame callbacks. A local `structuredClone` is sufficient; adding new state or a new API is unnecessary.
## Fix Focus Areas
- packages/cli/src/runtime-host-session-driver.ts[743-748]
- packages/cli/src/runtime-host-session-channel.ts[364-369]
- packages/cli/src/runtime-host-session-channel.ts[487-491]
- packages/cli/src/__tests__/runtime-host-session-driver.test.ts[69-150]

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


3. Stale generation check omitted in #replaceChannel 🐞 Bug☼ Reliability
Description
#replaceChannel publishes the new channel's goal to all #goalListeners unconditionally, without
checking #sessionId/#sessionGeneration the way the dedicated onGoalChanged callback in
#openSessionChannel does. If a session switch races (e.g. startNewSession() or a resume/attach
flow calling #replaceChannel back-to-back with an in-flight open), a stale or out-of-order goal
notification could reach listeners for a session that is no longer current.
Code

packages/cli/src/runtime-host-session-driver.ts[R743-748]

 async #replaceChannel(next: RuntimeHostSessionChannel | undefined): Promise<void> {
const previous = this.#channel;
this.#channel = next;
+ const goal = next?.snapshot.goal ?? null;+ for (const listener of this.#goalListeners) listener(goal);
await previous?.close().catch(() => undefined);
Relevance

●●● Strong

Generation guards are established reliability practice for stale asynchronous callbacks; this
omission creates the same race.

PR-#1661

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compare with the generation-guarded onGoalChanged callback added a few lines below (lines 933-938),
which explicitly checks `this.#sessionId !== sessionId || this.#sessionGeneration !==
sessionGeneration before notifying listeners. #replaceChannel` has no equivalent guard even though
it flips this.#channel and is called from multiple session-transition sites (session creation at
line 738, resume-like flow at line 476, startNewSession at line 568, and the attach flow at line
900), each of which is async and can interleave.

packages/cli/src/runtime-host-session-driver.ts[743-748]
packages/cli/src/runtime-host-session-driver.ts[933-938]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution
## Issue description
`#replaceChannel` in `packages/cli/src/runtime-host-session-driver.ts` notifies all `#goalListeners` with the new channel's goal every time it is called, but it does not verify that the channel being installed still corresponds to the driver's current `#sessionId`/`#sessionGeneration`. The sibling `onGoalChanged` callback passed into `#openSessionChannel` performs this check before forwarding to the same listener set, showing the intended invariant.
## Issue Context
`#replaceChannel` is called from several session-transition code paths (session creation, resume, `startNewSession`, attach-to-started-turn) that are async and can race with each other. A goal notification delivered through `#replaceChannel` during/after a session switch could report the wrong session's goal state to the TUI status line and `/goal` output.
## Fix Focus Areas
- packages/cli/src/runtime-host-session-driver.ts[743-748]
- packages/cli/src/runtime-host-session-driver.ts[933-938]

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



Informational

4. Waiting-status elapsed time is misleading 🐞 Bug≡ Correctness
Description
goalSummaryLines treats waiting as a live status via isLiveGoalStatus and appends an
ever-growing elapsed time computed as now - setAt, but goalElapsedMs never freezes the clock for
waiting (only paused/achieved freeze), so /goal reports total time since the goal was armed
rather than time in the current wait, which can overstate how long the loop has actually been
waiting after a long active/paused history.
Code

packages/cli/src/pi-goal.ts[R103-114]

+ // Terminal verdicts other than `achieved` carry no freeze timestamp, so a+ // wall-clock elapsed would keep growing for a loop that already ended.+ const elapsedMeaningful =+ isLiveGoalStatus(goal.status) || (goal.status === 'achieved' && goal.achievedAt !== null);+ const lines = [+ // A cleared goal keeps its terminal record, so say "cleared" up front+ // instead of presenting the condition as if it were still armed.+ goal.status === 'cleared'+ ? `Cleared goal: ${inline(goal.condition)}`+ : `Goal: ${inline(goal.condition)}`,+ elapsedMeaningful ? `${status} · ${formatGoalElapsed(goalElapsedMs(goal, now))}` : status,+ ];
Relevance

●●● Strong

Clear elapsed-time semantic inconsistency; deterministic fix aligns summary with its own
waiting-status rationale and feature intent.

PR-#3028

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
elapsedMeaningful in goalSummaryLines is `isLiveGoalStatus(goal.status) || (achieved &&
achievedAt); isLiveGoalStatus returns true for waiting`, so the summary shows
formatGoalElapsed(goalElapsedMs(goal, now)) where goalElapsedMs only freezes on
paused/achieved, meaning a waiting goal's displayed elapsed keeps growing with wall clock time
from setAt, conflating total goal age with the current waiting duration. This is the same
ambiguity the status-line comment (lines 80-82) explicitly calls out as a reason to hide elapsed for
waiting/paused there, but the summary function does not apply the same reasoning.

packages/cli/src/pi-goal.ts[51-62]
packages/cli/src/pi-goal.ts[103-114]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution
## Issue description
`/goal`'s summary shows a growing elapsed time for a goal in `waiting` status, computed as wall-clock since `setAt`, which conflates total goal age with time spent in the current waiting state — the opposite of the reasoning already applied to the status-line segment for the same status.
## Issue Context
`goalStatusLineText` deliberately omits elapsed for waiting/paused per its own comment (lines 80-82 of pi-goal.ts), but `goalSummaryLines` re-includes it for waiting via `isLiveGoalStatus`. This is a UX/consistency issue rather than a functional bug.
## Fix Focus Areas
- packages/cli/src/pi-goal.ts[103-114]
- packages/cli/src/pi-goal.ts[75-95]

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


5. Goal channel swap can drop in-flight notification 🐞 Bug☼ Reliability
Description
In #replaceChannel, this.#channel = next is set and the new goal is broadcast to listeners
before await previous?.close() runs, so any goal-changed frame the previous (outgoing) channel is
still processing during that close will be silently dropped, since its onGoalChanged callback
filters on this.#sessionId, which has already flipped to the new session by then.
Code

packages/cli/src/runtime-host-session-driver.ts[R743-749]

 async #replaceChannel(next: RuntimeHostSessionChannel | undefined): Promise<void> {
const previous = this.#channel;
this.#channel = next;
+ const goal = next?.snapshot.goal ?? null;+ for (const listener of this.#goalListeners) listener(goal);
await previous?.close().catch(() => undefined);
}
Relevance

●● Moderate

Potential close-order race is plausible, but history provides no close matching precedent for
required replacement ordering.

PR-#1661

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
#replaceChannel sets this.#channel = next and fires listeners with next's goal synchronously,
then awaits previous?.close(). Any goal-changed frame the previous channel is mid-processing when
close() resolves will be filtered out by the sessionId check in the onGoalChanged callback
(lines 933-938) because this.#sessionId has already moved to the new session.

packages/cli/src/runtime-host-session-driver.ts[743-749]

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 goal-changed event that the outgoing channel is mid-delivering during a session swap can be silently dropped, because the sessionId guard in `onGoalChanged` compares against the driver's already-updated `#sessionId`.
## Issue Context
This is a narrow race during session switching; the impact is a single potentially-missed goal transition notification for the outgoing session, whose state is discarded anyway once the session changes. Low likelihood and low impact, worth a follow-up rather than blocking.
## Fix Focus Areas
- packages/cli/src/runtime-host-session-driver.ts[743-749]
- packages/cli/src/runtime-host-session-driver.ts[933-938]

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


Grey Divider

Context
Review mode: 🧠 Deep: This is a substantial cross-cutting behavioral change spanning TUI rendering, command routing, session-driver contracts, continuity snapshots, push notifications, reconnect/session replacement, and multiple state paths, creating a dense set of independent defects that benefits from redundant review.

Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I reviewed exact head 7e94b22ff5fecdc07392c08c3e6bbb9592c14a27, including the full diff, current CI, merge state, and the available automated feedback. I found no reproducible P0–P2 production issue.

The problem and ownership model are correct. Runtime Host continuity remains the sole goal authority; the TUI consumes the existing pushed projection without adding polling, a goal RPC, or a second cache. Goal-origin transcript entries come from stored provenance, /goal is a local read-only command, and reconnect/replay behavior remains projection-driven. This is a cohesive and appropriately scoped observability slice.

A non-blocking P3 hardening opportunity remains: getGoal() and the channel-adoption callback expose the live projection object rather than a defensive clone. No current production listener mutates it, so this is not a demonstrated user-facing defect, but cloning at that boundary would make the runtime ownership guarantee explicit and consistent with the other notification paths.

I did not find low-quality test blocks to delete or a useful reason to split the PR.

Approved with the defensive-clone follow-up noted.

Disclosure: Codex performed the read-only source, lifecycle, test, CI, and feedback analysis. The human contributor remains responsible for independently verifying the final diff and owns the approval decision.

中文

当前没有 P0–P2。TUI 直接消费 Runtime Host goal projection,没有新增轮询或重复状态。可写引用未 clone 属 P3 防御性收口,不阻塞 Approve。

An armed goal burns tokens between prompts, but the TUI showed nothing:
goal continuation turns rendered as plain user prompts, the status line
had no goal segment, and the only way to inspect the loop was spending a
model turn on GoalStatus.
- Status line shows a live goal (active/waiting/paused) with the
iteration counter and elapsed wall-clock; terminal goals stay hidden,
matching the desktop chip.
- Goal-origin turns render with a "Goal continuation (autonomous)"
provenance header instead of as user prompts.
- /goal prints condition, status, iterations, elapsed, tokens vs budget,
and the evaluator's last note without burning a turn, and works while
the loop is busy.
- Goal state rides the session subscription's continuity snapshot — the
same push channel the desktop observer diffs — so every transition
(set, evaluator settle, abort auto-pause, waiting wake, terminal
verdict, cross-client control) reaches the TUI as it happens, with no
polling and no stale window.
Ref apache#3022
Generated-by: Maka
Keep the standalone visibility branch type-safe after the goal command entered the shared TUI catalog.
Generated-by: Maka
@me2seeks
me2seeksforce-pushed the feat/cli-goal-visibility branch from 7e94b22 to bd4c4efCompareAugust 18, 2026 15:38
@me2seeks

Copy link
Copy Markdown
ContributorAuthor

@Astro-Han This branch is rebased on current main and preserves the approved Goal visibility design while composing the new locale guidance catalog. CLI passes 288/288 locally. Could you re-review the rebased head when convenient?

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The PR uses the right authority and the smallest useful seam: the TUI projects the Runtime Host continuity snapshot it already receives, /goal is handled locally, and no polling, extra RPC, or parallel goal state is introduced. Reconnect, Session switching, revision updates, and goal-origin provenance remain consistent. All current CI is green, and I found no blocking correctness or lifecycle issue.

One help-copy mismatch is noted inline as non-blocking polish.

AI-assisted review disclosure: Codex verified the final diff, continuity subscription flow, local command routing, status/summary projection, reconnect lifecycle, focused tests, and live CI. Two independent reviewer-agent passes and an OpenCode Go DeepSeek V4 Flash (high) adversarial pass were used as inputs. No local tests were run.

中文复核

这个 PR 使用了正确且最小的 seam:TUI 直接投影已经收到的 Runtime Host continuity snapshot,/goal 在本地处理,没有引入轮询、额外 RPC 或第二份 goal 状态。重连、Session 切换、revision 更新与 goal-origin provenance 保持一致。当前 CI 全绿,未发现阻塞性的正确性或生命周期问题。行内仅留了一处不阻塞的 help 文案建议。

本次为 AI 辅助审查:Codex 核验最终 diff、continuity subscription、本地命令路由、状态/摘要投影、重连生命周期、聚焦测试与实时 CI;另使用两次独立 reviewer 及一次 OpenCode Go DeepSeek V4 Flash(high)对抗审查。未运行本地测试。

Comment threadpackages/cli/src/tui-primary-guidance.ts Outdated

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The latest commit only corrects /goal guidance to match this PR's status-only scope, and the full current diff still keeps Runtime Host continuity projection as the sole authority—no polling, duplicate goal state, or parallel RPC path.

No remaining P0-P2 findings. The defensive-clone idea is optional hardening and should not expand this focused change.

AI-assisted review disclosure: Codex re-reviewed exact head 07b4cbd, including the one-commit delta, current CI, and thread state; all checks are green and no unresolved review threads remain.

中文说明

最新提交只修正了 /goal 帮助文案,使其与本 PR 的“仅展示状态”范围一致。完整 diff 仍由 Runtime Host continuity projection 作为唯一权威,没有引入轮询、重复状态或并行 RPC。没有剩余 P0-P2,可以合并。

@Astro-Han

Copy link
Copy Markdown
Contributor

Everything looks good, before we merge this PR into main, could we have a before after screenshot on PR body? Thanks!

@me2seeks

Copy link
Copy Markdown
ContributorAuthor

Added the requested Before/After comparison to the PR body. It shows the same goal-origin message before the feature and, after it, the autonomous provenance, local /goal summary, and live status-line segment.

@Astro-Han
Astro-Han merged commit 39dd638 into apache:mainAug 19, 2026
19 checks passed
Sign up for freeto 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.

2 participants

@me2seeks@Astro-Han