Skip to content

refactor prompt seeding to a unified steer/queue api#336

Open
Nek-12 wants to merge 34 commits into
fix/workflow-editor-protocol-promptsfrom
refactor-steering
Open

refactor prompt seeding to a unified steer/queue api#336
Nek-12 wants to merge 34 commits into
fix/workflow-editor-protocol-promptsfrom
refactor-steering

Conversation

@Nek-12

@Nek-12 Nek-12 commented Jun 9, 2026

Copy link
Copy Markdown
Member
  • update default system prompts
  • refactor: inline runtime runprompt helpers
  • refactor: inline runtime status helpers
  • refactor: inline runtime tool event copies
  • refactor: inline runtime transcript helpers
  • refactor: inline tool formatting helpers
  • refactor: inline server utility helpers
  • refactor: inline transport transcript helpers
  • refactor: inline semantic helper slice
  • refactor: inline runtime semantic helpers
  • refactor: inline shared semantic helpers
  • fix: preserve workflow parameter input focus
  • fix: refactor steering to use a unified api

Summary by CodeRabbit

Release Notes

  • New Features

    • Added workflow graph wiring derivation endpoint for improved workflow definition processing.
    • Enhanced workflow draft validation with layout projection for better real-time feedback.
  • Improvements

    • Improved workflow parameter editing with stable row identification for better reliability.
    • Enhanced runtime output routing through typed steering intents for more consistent behavior.
    • Better session state tracking and headless mode management across workflows and compaction.
    • Refined workflow completion guidance and reviewer feedback prompts.
  • Documentation

    • Added engineering guidelines for unit tests and runtime output boundaries.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • production
  • prod

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d739d426-d81d-4660-a0ff-76c537096c08

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-steering

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

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🧹 Nitpick comments (4)
server/runtime/engine_part11_test.go (1)

355-359: 💤 Low value

Consider safer type assertion to avoid panic.

The unchecked type assertion on line 355 will panic if eng.messageFlow is not of type *defaultMessageLifecycle. While acceptable in test code (the panic would fail the test), a checked assertion would provide clearer failure messages and make the test more resilient to implementation changes.

♻️ Proposed refactor for safer assertion
-	messageFlow := eng.messageFlow.(*defaultMessageLifecycle)
-	var messages []QueuedUserMessage
-	if messageFlow != nil && messageFlow.queue != nil {
-		messages = messageFlow.queue.Snapshot()
-	}
+	var messages []QueuedUserMessage
+	if messageFlow, ok := eng.messageFlow.(*defaultMessageLifecycle); ok && messageFlow != nil && messageFlow.queue != nil {
+		messages = messageFlow.queue.Snapshot()
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/runtime/engine_part11_test.go` around lines 355 - 359, Replace the
unchecked type assertion on eng.messageFlow with a checked (comma-ok) assertion:
attempt to cast eng.messageFlow to *defaultMessageLifecycle and, if the
assertion fails, call the test failure helper (e.g., t.Fatalf or t.Fatalf-like)
with a clear message mentioning eng.messageFlow and defaultMessageLifecycle;
then proceed to read messageFlow.queue and call Snapshot() only when messageFlow
and messageFlow.queue are non-nil, returning or failing early otherwise so the
test reports a clear, non-panic error.
server/runtime/exclusive_step.go (1)

106-106: ⚡ Quick win

Verify ignoring steerEvent error is safe in deferred cleanup.

The error from steerEvent is explicitly ignored (_). In this deferred cleanup path, if steering the EventInFlightClearFailed event fails, the failure is already being joined into the returned error via errors.Join(err, wrapped) at line 107. However, the event might not be observable to clients.

Please confirm this is acceptable behavior: if the event steering fails during cleanup, is it sufficient to return the error without the event being emitted, or should this be logged/handled differently?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/runtime/exclusive_step.go` at line 106, The deferred call to
s.engine.steerEvent(EventInFlightClearFailed) currently discards its error which
can hide failure to emit the event; change the cleanup to capture the steerEvent
error and either (a) log it via the component logger (e.g., s.logger.Errorf or
s.engine.logger) so the missing event is observable, or (b) include it in the
returned error by joining it with errors.Join(err, wrapped, steerErr); update
the call site that currently invokes steerEvent(...) (look for steerEvent and
EventInFlightClearFailed) to handle steerErr accordingly so failures to emit the
event are not silently ignored.
server/runtime/engine_message_ops.go (2)

80-88: 💤 Low value

Remove unused function appendUserMessageWithoutConversationUpdate.

Static analysis indicates this function is unused after the steering migration. Consider removing it to avoid dead code accumulation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/runtime/engine_message_ops.go` around lines 80 - 88, The function
appendUserMessageWithoutConversationUpdate is dead code after the steering
migration; remove this function definition from Engine to avoid unused code
accumulation and, if present, also remove any now-unused helper
steerUserMessageWithoutDerivedEventIntent to keep the codebase clean; ensure any
callers are updated (none should exist per static analysis) and run tests/build
to confirm no references remain.

Source: Linters/SAST tools


259-301: 💤 Low value

Remove unused function appendMessageWithoutConversationUpdate.

Static analysis indicates this function is unused after the steering migration. Consider removing it to avoid dead code accumulation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/runtime/engine_message_ops.go` around lines 259 - 301, Remove the dead
helper appendMessageWithoutConversationUpdate from Engine, since it is no longer
referenced after the steering migration. Delete the unused method and verify
there are no remaining call sites or interface/usage expectations tied to
steerMessageWithoutDerivedEventIntent in this path; if that intent helper
becomes unused as a result, clean it up as well.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx`:
- Around line 126-141: The canvas currently drops execution-only errors because
cleanLayoutValidation and graphValidation prefer cachedDraftValidation and never
merge execution results; add a helper mergeWorkflowValidations(draft, execution)
that returns execution when draft is null, draft when execution is null, or a
merged Validation (valid = draft.valid && execution.valid, errors =
[...draft.errors, ...execution.errors]) and replace usages: compute
cachedDraftValidation and cachedExecutionValidation as before, then set
cleanLayoutValidation = mergeWorkflowValidations(cachedDraftValidation,
cachedExecutionValidation) and set graphValidation = dirty.graphDirty ?
emptyWorkflowValidation : mergeWorkflowValidations(draftValidation,
executionValidation); also use the helper when computing layoutValidation where
you currently pick between draft/execution so execution-only errors are
preserved on the layout.

In `@prompts/reviewer_system_prompt.md`:
- Line 9: Fix the spelling mistake in the reviewer system prompt sentence where
"confrm" is used; locate the sentence "As a supervisor, your responsibilities
are to catch errors in model outputs, prevent hallucinations, ensure output
quality and worker diligence, confrm and enforce instruction following, send
reminders about unfinished work or incomplete plan items, prevent regressions,
review code, and maintain high-quality project architecture." and replace
"confrm" with "confirm" so it reads "...ensure output quality and worker
diligence, confirm and enforce instruction following...".

In `@server/runtime/tool_executor.go`:
- Line 48: The call to e.steerEvent(stepID, started) currently discards its
error; update the code in tool_executor.go to check the returned error from
e.steerEvent and handle it consistently with other event calls (either log the
error via the existing logger or return/propagate the error so transcript
consistency is preserved), ensuring that failures to persist the "started" event
are not silently ignored while subsequent e.steer(...) tool completion calls
still run; reference the e.steerEvent invocation and the surrounding
e.steer(...) completion handling to implement the error check and choose logging
or propagation to maintain event pairing.

In `@server/tools/transcript_contracts.go`:
- Around line 777-781: formatOutputDefault currently swallows json.Marshal
errors by returning "", which lets formatGenericToolResult misreport success as
"done"; change formatOutputDefault to capture and log the marshal error and
return a safe fallback string (e.g., a trimmed raw JSON string or a sentinel
like "<marshal error: ...>") instead of "", and/or return an explicit error
indicator that formatGenericToolResult can detect; then update
formatGenericToolResult to treat that sentinel / error return as a tool failure
(so it yields "tool failed" and includes the marshal error details) rather than
silently reporting "done". Ensure you update the implementations of
formatOutputDefault and formatGenericToolResult to reference their existing
function names so the fallback is logged/propagated instead of discarded.

---

Nitpick comments:
In `@server/runtime/engine_message_ops.go`:
- Around line 80-88: The function appendUserMessageWithoutConversationUpdate is
dead code after the steering migration; remove this function definition from
Engine to avoid unused code accumulation and, if present, also remove any
now-unused helper steerUserMessageWithoutDerivedEventIntent to keep the codebase
clean; ensure any callers are updated (none should exist per static analysis)
and run tests/build to confirm no references remain.
- Around line 259-301: Remove the dead helper
appendMessageWithoutConversationUpdate from Engine, since it is no longer
referenced after the steering migration. Delete the unused method and verify
there are no remaining call sites or interface/usage expectations tied to
steerMessageWithoutDerivedEventIntent in this path; if that intent helper
becomes unused as a result, clean it up as well.

In `@server/runtime/engine_part11_test.go`:
- Around line 355-359: Replace the unchecked type assertion on eng.messageFlow
with a checked (comma-ok) assertion: attempt to cast eng.messageFlow to
*defaultMessageLifecycle and, if the assertion fails, call the test failure
helper (e.g., t.Fatalf or t.Fatalf-like) with a clear message mentioning
eng.messageFlow and defaultMessageLifecycle; then proceed to read
messageFlow.queue and call Snapshot() only when messageFlow and
messageFlow.queue are non-nil, returning or failing early otherwise so the test
reports a clear, non-panic error.

In `@server/runtime/exclusive_step.go`:
- Line 106: The deferred call to s.engine.steerEvent(EventInFlightClearFailed)
currently discards its error which can hide failure to emit the event; change
the cleanup to capture the steerEvent error and either (a) log it via the
component logger (e.g., s.logger.Errorf or s.engine.logger) so the missing event
is observable, or (b) include it in the returned error by joining it with
errors.Join(err, wrapped, steerErr); update the call site that currently invokes
steerEvent(...) (look for steerEvent and EventInFlightClearFailed) to handle
steerErr accordingly so failures to emit the event are not silently ignored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 608ec292-dae3-429f-992d-97dfc9431201

📥 Commits

Reviewing files that changed from the base of the PR and between dc55ebe and 36083fe.

📒 Files selected for processing (95)
  • AGENTS.md
  • apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.test.tsx
  • apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
  • apps/desktop/src/features/workflow-editor/WorkflowInspectorSidebar.tsx
  • apps/desktop/src/features/workflow-editor/workflowEditorDraft.test.ts
  • apps/desktop/src/features/workflow-editor/workflowEditorDraft.ts
  • apps/desktop/src/features/workflow-editor/workflowGraphLayout.ts
  • docs/dev/specs/core-runtime-tools.md
  • docs/dev/specs/tui-transcript.md
  • prompts/embed.go
  • prompts/embed_test.go
  • prompts/reviewer_system_prompt.md
  • prompts/tool_preambles_prompt.md
  • prompts/workflow/final_answer_nudge.md
  • server/runprompt/headless.go
  • server/runprompt/headless_test.go
  • server/runprompt/service.go
  • server/runtime/background.go
  • server/runtime/background_test.go
  • server/runtime/chat_store_part2_test.go
  • server/runtime/compaction.go
  • server/runtime/compaction_carryover.go
  • server/runtime/compaction_executor.go
  • server/runtime/compaction_overflow_repair.go
  • server/runtime/compaction_persistence.go
  • server/runtime/compaction_planner.go
  • server/runtime/compaction_reminder.go
  • server/runtime/compaction_utils.go
  • server/runtime/engine.go
  • server/runtime/engine_message_ops.go
  • server/runtime/engine_part10_test.go
  • server/runtime/engine_part11_test.go
  • server/runtime/engine_part15_test.go
  • server/runtime/engine_queue_submission.go
  • server/runtime/engine_queue_submission_test.go
  • server/runtime/engine_reviewer_helpers.go
  • server/runtime/engine_state.go
  • server/runtime/exclusive_step.go
  • server/runtime/exclusive_step_test.go
  • server/runtime/goal.go
  • server/runtime/message_lifecycle.go
  • server/runtime/meta_context.go
  • server/runtime/meta_context_architecture_test.go
  • server/runtime/meta_context_runtime.go
  • server/runtime/orchestration_collaborators.go
  • server/runtime/output_steering.go
  • server/runtime/persisted_transcript_scan.go
  • server/runtime/queued_user_messages.go
  • server/runtime/request_cache_lineage.go
  • server/runtime/request_cache_lineage_test.go
  • server/runtime/reviewer_pipeline.go
  • server/runtime/state_stores_test.go
  • server/runtime/step_executor.go
  • server/runtime/subagents_test.go
  • server/runtime/tool_executor.go
  • server/runtime/tool_presentation.go
  • server/runtime/transcript_persistence.go
  • server/runtime/transcript_scan.go
  • server/runtime/workflow_completion.go
  • server/runtime/workflow_completion_test.go
  • server/runtime/worktree_reminder.go
  • server/runtimewire/runtimewire_test.go
  • server/runtimewire/wiring.go
  • server/session/fork.go
  • server/session/store.go
  • server/sessionview/dormant_cache.go
  • server/sessionview/snapshot.go
  • server/startup/startup.go
  • server/startup/startup_test.go
  • server/tools/edit/matcher.go
  • server/tools/patch/errors.go
  • server/tools/patch/tool.go
  • server/tools/patch/tool_commit.go
  • server/tools/patch/tool_state.go
  • server/tools/shell/manager.go
  • server/tools/shell/manager_notice.go
  • server/tools/shell/manager_output.go
  • server/tools/shell/manager_types.go
  • server/tools/shell/tool.go
  • server/tools/transcript_contracts.go
  • server/transport/gateway.go
  • server/transport/gateway_stream_handlers.go
  • server/transport/gateway_test.go
  • server/workflowstore/graph_save.go
  • server/workflowstore/protocol_violations.go
  • server/workflowstore/store.go
  • server/workflowstore/transitions.go
  • server/workflowview/service.go
  • shared/client/remote_rpc.go
  • shared/client/remote_stream.go
  • shared/config/config_overlay.go
  • shared/config/config_registry.go
  • shared/rpcwire/websocket.go
  • shared/transcript/patchformat/render.go
  • shared/transcriptdiag/diag.go
💤 Files with no reviewable changes (5)
  • server/runprompt/service.go
  • shared/config/config_overlay.go
  • server/tools/shell/tool.go
  • shared/client/remote_rpc.go
  • server/session/fork.go

Comment thread apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx Outdated
Comment thread prompts/reviewer_system_prompt.md Outdated
Comment thread server/runtime/tool_executor.go Outdated
Comment thread server/tools/transcript_contracts.go
Comment thread prompts/embed_test.go Outdated
Comment thread server/runtime/compaction.go Outdated
Comment thread server/runtime/compaction.go Outdated
Comment thread server/runtime/compaction.go
Comment thread server/runtime/compaction.go
Comment thread server/session/store.go Outdated
Comment thread server/session/store.go Outdated
Comment thread server/session/store.go Outdated
Comment thread server/session/store.go Outdated
Comment thread server/session/store.go Outdated
Nek-12 added 5 commits June 9, 2026 12:32
Replace one-line wrappers (appendMessage, appendUserMessage,
appendAssistantMessage, persistToolCompletion, appendPersistedLocalEntry*,
clearStreamingAssistantState, steerReasoningEntries, etc.) with direct
steer/intent calls so all runtime output mutations go through a single
unified steering API.

Also fixes typo in reviewer system prompt, removes useless string-asserting
test for WorkflowFinalAnswerNudgePrompt, adds AGENTS.md rule against such
tests, and propagates steerEvent error from tool start in tool_executor.

Addresses review threads on PR #336 (engine_message_ops, tool_executor,
embed_test, reviewer_system_prompt).
Remove emit/emitConversationUpdated/emitCommittedTranscriptAdvanced/
emitCommittedMessageTranscriptAdvanced and their steer-side equivalents,
plus appendGoalDeveloperMessage and steerPersistedGoalDeveloperMessage.
All call sites now construct steerEventIntent / steerMessageIntent inline.

Also:
- Drop the duplicate "User ran shell command directly" developer message in
  SubmitUserShellCommand; the user_initiated tool-call already carries the
  meta-context, so detail mode no longer renders the command twice.
- Replace ad-hoc "1 suggestion"/"%d suggestions" with a pluralizeEnglish
  helper for reviewer status text.
- Split goal loop persistence failure into a separate transcript error so
  it does not overflow the status line.
…text

- Switch the precise input-token cache key from the raw JSON request payload
  to its sha256 digest so large payloads no longer balloon the in-memory map.
- Stop falling back to time.Now() inside the meta context builder when the
  caller passes a zero timestamp; require all callers to pass a real time and
  fix the lone caller (skillsContextMessageWithDisabled).
- Coalesce skill-discovery warnings into a single transcript message rather
  than emitting one per warning.
…on fallback

- Merge cached draft and execution validation results when computing the
  workflow editor's layout/graph validation so execution-only errors stay
  visible on the canvas instead of collapsing into the empty draft result.
- formatOutputDefault now falls back to the trimmed raw JSON string when
  json.Marshal fails so successful tool calls no longer get reported as the
  default "done" status when serialization breaks down.
…eral

Restore a named token-estimator helper instead of repeating the
(len + 3) / 4 idiom in compaction sizing, and store the collapsed-shell
fallback as a package-level JSON RawMessage so the json.Marshal failure
branch in collapsedCompactionOverflowShellOutput stops re-deriving it.
Nek-12 added 2 commits June 9, 2026 12:51
- Remove Store.MarkAgentsInjected, Store.AppendEvent (the WithCommitStatus-
  dropping variant), Store.appendObservedEventsLocked,
  Store.appendEventsAtomicLocked, and unlockAndObservePersistenceWithCommitStatus.
  Callers now use SetAgentsInjected(true), the 3-return AppendEvent (now
  always exposing commit status), or the inlined unlock-observe pattern.
…ms wrapper

InjectAgentsIfNeeded just delegated to steerBaseMetaContextIfNeeded; remove
the messageLifecycle interface method and the engine alias. compactionSeedItems
was an unused alias for llm.CloneResponseItems.

@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: e29923dd24

ℹ️ 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 thread apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
Comment thread apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
Comment thread apps/desktop/src/features/workflow-editor/workflowGraphLayout.ts Outdated
Comment thread apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
Nek-12 added 2 commits June 9, 2026 13:57
…a guard

Base meta context (AGENTS.md/skills/subagents/environment) is now injected
once via an in-process guard instead of a persisted session.Meta field and a
SQLite column. The guard is reset by history replacement and re-set after
compaction reinjection, and derived from transcript presence on resume, so
the self-heal-after-bare-replacement behavior is preserved without the
missing-message walk.

Drops sessions.agents_injected via migration 00032 (regenerated sqlc).
…pt scan

Headless state now lives in session.Meta.HeadlessActive (persisted in
session.json and mirrored into the metadata read model) rather than being
re-derived by scanning the conversation for enter/exit markers. The transition
reconciles the launch mode (cfg.HeadlessMode) against the persisted flag:
entering headless appends the enter prompt once and sets the flag, returning to
interactive appends the exit prompt once and clears it, and matching states are
a no-op so repeated --continue launches never duplicate the prompt. Compaction
reinjects the enter prompt after the carryover/handoff messages when the flag is
set, and forks inherit it. Removes the chat-store headless scan and the
headlessModeActive/shouldInjectHeadlessModePromptForState helpers.

@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: 7b660bc656

ℹ️ 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 thread server/runtime/meta_context_runtime.go
Comment thread server/session/fork.go Outdated
Nek-12 added 2 commits June 9, 2026 14:50
… of a stub

compact_and_continue_session previously fabricated a developer "compacted
continuation" message into a fresh cross-role child session, never actually
compacting the source. It now reuses the real /compact flow: a linear
continuation continues in the source session in place and runs
engine.CompactContext before the node turn, while a fan-out branch first clones
the source session (new session.CloneSession) so parallel branches never compact
or mutate the shared source concurrently. The mode now carries the same
subagent-role requirement as continue_session.

RunStartContext.IsFanoutBranch surfaces the scheduler's existing parallel-branch
marker so the starter can choose fork vs in-place.
Base meta context is now reinjected as part of the single history_replaced
commit instead of a separate steer afterward, so a compacted active list is
born carrying it atomically (summary precedes meta in both provider and
transcript order). The base-meta guard is now a deterministic length check —
seeded from restored-history length at startup and replacement length after
compaction — with no transcript scan and no persisted flag: every session's
active list is born with base meta, so re-injection cannot occur. Removes the
missing-message presence walk and its helpers, and drops the self-heal repair
tests that simulated a now-impossible bare-replacement state.
Nek-12 added 3 commits June 9, 2026 15:35
…eleted nodes

- Memoize the merged clean validation so the render-time layout-snapshot update
  no longer sees a fresh object every render (was a potential "too many
  re-renders" loop in the clean editor state). [P1]
- Vary the draft-validation query key by draft metadata so display-name/
  description edits revalidate instead of reusing the staleTime:Infinity result. [P2]
- Drop draft entities that no longer resolve to a model when projecting a dirty
  draft onto the previous layout, so deleted nodes/groups/edges stop rendering
  until the next ELK layout. [P2]
…le editing

Adds a lightweight workflow.graph.deriveWiring RPC that returns only the derived
wiring for a draft graph, skipping the expensive validation modes. The editor
runs it as a dedicated query enabled during the dirty period (keyed on
graphVersion, which only bumps on real graph changes), so edge/node inspector
wiring suggestions stay current while editing instead of falling back to stale
pre-edit wiring until save/reload. Keeps wiring server-authoritative rather than
recomputing it client-side.
The persisted Meta.HeadlessActive flag is now seeded from the restored
transcript on session open, which both keeps it authoritative and migrates
sessions created before the flag existed (whose metadata has no flag but whose
transcript may end in a headless marker) — otherwise reopening a headless
session interactively skipped the exit prompt and continuing it headlessly
duplicated the enter prompt. ForkAtUserMessage now derives the child's flag from
the replayed events (the state at the fork boundary) instead of copying the
parent's latest flag. The transcript scan is used only at these restore/fork
boundaries; per-request transitions still read the persisted flag.

@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: 2151c6cfdf

ℹ️ 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 thread apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
Comment thread server/workflowrunner/starter.go
Comment thread server/workflowrunner/starter.go Outdated
…on field edits

- StartWorkflowRun no longer cleans up the plan store on setup failure when the
  plan reuses an existing session (resume, continue, or in-place
  compact-and-continue) — previously a setup failure could delete the prior
  node's persisted session. Only fresh/cloned run sessions stay disposable.
- Skip the pre-turn compaction when resuming a started compact-and-continue run
  (input.Run.SessionID already set), so an interrupted run does not recompact
  its already-compacted history on retry.
- Key the derive-wiring query on the draft graph content instead of graphVersion,
  since wiring-relevant edits (node input fields, edge parameters) leave
  graphVersion unchanged and would otherwise serve stale wiring.

@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: eb9d5bb2e3

ℹ️ 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 thread server/workflowrunner/starter.go Outdated
Comment thread server/runtime/message_lifecycle.go
Comment thread apps/desktop/src/features/workflow-editor/workflowGraphLayout.ts
Nek-12 added 4 commits June 9, 2026 16:30
- Route policy now short-circuits auth gate when RequiresStartupAuth is
  false (non-first-party openai_base_url), so session.plan and
  session.runtime.activate are no longer blocked for local-provider
  users with no auth configured
- serviceBaseURL no longer overrides an explicit base URL with the
  hardcoded codex endpoint when OAuth is active; explicit URL wins
- Fix double "server auth is not configured" error caused by
  errors.Join duplicating the sentinel message back to itself
Gating compact_and_continue on a populated run SessionID was wrong:
AttachRunSession persists the reused source session before CompactContext
commits, so a run interrupted during compaction skipped it on resume and
continued from un-compacted history. Record the committing run in the
history_replaced payload, rebuild it on restore, and gate on that instead
so compaction happens exactly once per handoff.
The dirty-graph projection reused the stale ELK layout object and only
refreshed node/edge data, so a re-targeted edge stayed attached to its old
endpoint and a regrouped node rendered in the wrong container until the next
layout (or indefinitely if layout failed). Reconnect edge endpoints from the
draft model and drop a node whose group membership changed until ELK relays.
@Nek-12

Nek-12 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/workflowstore/runs.go (1)

293-314: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Propagate IsFanoutBranch on the runnable return path.

StartWorkflowRun() bails out when WorktreeID/WorktreeRoot are empty, so every real runtime start uses this return block. Because IsFanoutBranch is only populated in the earlier no-worktree branch, fan-out compact_and_continue_session runs arrive downstream as false here and get treated as in-place reuse instead of isolated clones.

Suggested fix
 	return RunStartContext{
 		Run:                  runRecordFromTaskRun(run),
 		Task:                 taskRecordFromTask(task),
 		Workflow:             workflowRecord,
 		Node:                 nodeRecordFromSnapshot(snapshot.Node, snapshot.WorkflowID),
 		ContextMode:          transitionContext.ContextMode,
 		SourceRunID:          transitionContext.SourceRunID,
 		SourceSessionID:      transitionContext.SourceSessionID,
 		SourceNode:           transitionContext.SourceNode,
+		IsFanoutBranch:       isFanoutBranch,
 		TransitionIDs:        transitionIDsFromSnapshot(snapshot),
 		TransitionOptions:    transitionOptionsFromSnapshot(snapshot),
 		PromptTemplate:       strings.TrimSpace(runMetadata.PromptTemplate),
 		Parameters:           parameters,
 		ParameterValues:      parameterValues,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/workflowstore/runs.go` around lines 293 - 314, The RunStartContext
return in StartWorkflowRun is missing propagation of IsFanoutBranch so fan-out
runs are misclassified; update the returned RunStartContext (in the return block
that currently sets Run, Task, Workflow, Node, etc.) to include IsFanoutBranch
sourced from the transitionContext (e.g., transitionContext.IsFanoutBranch) so
the same flag set in the earlier no-worktree branch is preserved for actual
runtime starts; ensure you use transitionContext.IsFanoutBranch (with a sensible
default if nil) when constructing the RunStartContext.
🧹 Nitpick comments (1)
server/workflowsvc/service_test.go (1)

967-969: ⚡ Quick win

Assert derived wiring identity, not only count.

This check can pass even with wrong edge derivation as long as cardinality matches. Validate per-edge identity/mapping to avoid false positives.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/workflowsvc/service_test.go` around lines 967 - 969, The test
currently only compares the lengths of derived.DerivedWiring.Edges and
graph.Edges; update it to assert identity/mapping for each edge by iterating
both slices and comparing unique identifiers or full edge structs (e.g., compare
edge.ID or all relevant fields) rather than just counts, and fail the test with
a helpful message when any derived edge doesn't match the expected graph edge;
you can use reflect.DeepEqual or a comparison utility (like cmp.Diff) to produce
readable diffs for mismatches and refer to derived.DerivedWiring.Edges and
graph.Edges to locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/runtime/committed_transcript_events_test.go`:
- Around line 36-37: The test currently ignores the error returned by
eng.steer("stream-step", steerClearStreamingStateIntent()), which can mask
steering failures; update the test to capture and assert the error (e.g., if err
:= eng.steer(...); err != nil { t.Fatalf(...) }) so steering failures fail fast
with a clear message instead of producing misleading downstream assertion
failures in assertEventFlags; references: eng.steer and
steerClearStreamingStateIntent and assertEventFlags.

In `@server/workflowrunner/starter.go`:
- Around line 328-335: When a disposable fan-out clone is created by
cloneSourceSessionForFanout(), ensure it and its transient stores are always
cleaned up if any subsequent step fails: after calling
cloneSourceSessionForFanout() (in the block using continuationSessionID and the
similar block at lines 355-371) immediately register a deferred/cleanup path or
try/finally so that if planner.PlanSession(...) or plan.Store.EnsureDurable()
(or any later error) occurs you delete the cloned session and close the
transient sourceStore and cloned store handles; also close those stores on the
success path once they are no longer needed. Use the same session ID and store
references returned by cloneSourceSessionForFanout(), and ensure cleanup runs on
both error and normal exit so no unattached session or open store is left
behind.

---

Outside diff comments:
In `@server/workflowstore/runs.go`:
- Around line 293-314: The RunStartContext return in StartWorkflowRun is missing
propagation of IsFanoutBranch so fan-out runs are misclassified; update the
returned RunStartContext (in the return block that currently sets Run, Task,
Workflow, Node, etc.) to include IsFanoutBranch sourced from the
transitionContext (e.g., transitionContext.IsFanoutBranch) so the same flag set
in the earlier no-worktree branch is preserved for actual runtime starts; ensure
you use transitionContext.IsFanoutBranch (with a sensible default if nil) when
constructing the RunStartContext.

---

Nitpick comments:
In `@server/workflowsvc/service_test.go`:
- Around line 967-969: The test currently only compares the lengths of
derived.DerivedWiring.Edges and graph.Edges; update it to assert
identity/mapping for each edge by iterating both slices and comparing unique
identifiers or full edge structs (e.g., compare edge.ID or all relevant fields)
rather than just counts, and fail the test with a helpful message when any
derived edge doesn't match the expected graph edge; you can use
reflect.DeepEqual or a comparison utility (like cmp.Diff) to produce readable
diffs for mismatches and refer to derived.DerivedWiring.Edges and graph.Edges to
locate the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4fd2c0dc-38ae-42de-8d68-4af2a08e7d47

📥 Commits

Reviewing files that changed from the base of the PR and between 36083fe and 3e29e7e.

📒 Files selected for processing (118)
  • .claude/skills
  • AGENTS.md
  • CLAUDE.md
  • apps/desktop/src/api/client.ts
  • apps/desktop/src/api/schemas/workflow.ts
  • apps/desktop/src/app/queryKeys.ts
  • apps/desktop/src/features/workflow-editor/WorkflowEditorRoute.tsx
  • apps/desktop/src/features/workflow-editor/workflowGraphLayout.test.ts
  • apps/desktop/src/features/workflow-editor/workflowGraphLayout.ts
  • cli/app/session_lifecycle_part2_test.go
  • cli/app/session_lifecycle_test.go
  • cli/app/ui_mode_flow_test.go
  • cli/app/ui_part4_test.go
  • cli/app/ui_part5_test.go
  • cli/app/ui_part7_test.go
  • cli/app/ui_runtime_adapter_part3_test.go
  • cli/app/ui_runtime_client_test.go
  • cli/app/ui_runtime_status_test.go
  • prompts/reviewer_system_prompt.md
  • prompts/system_prompt/harness_workflow_autonomy.md
  • server/core/bundles.go
  • server/core/composition_test.go
  • server/core/core.go
  • server/embedded/embedded_test.go
  • server/launch/planner_test.go
  • server/lifecycle/lifecycle_test.go
  • server/llm/openai_http_test.go
  • server/llm/openai_http_transport_helpers.go
  • server/metadata/migrations/00032_drop_session_agents_injected.up.sql
  • server/metadata/queries.sql
  • server/metadata/sqlitegen/models.go
  • server/metadata/sqlitegen/queries.sql.go
  • server/metadata/store.go
  • server/metadata/store_part2_test.go
  • server/metadata/store_test.go
  • server/runtime/chat_store.go
  • server/runtime/committed_transcript_events_test.go
  • server/runtime/compaction.go
  • server/runtime/compaction_carryover.go
  • server/runtime/compaction_executor.go
  • server/runtime/compaction_overflow_repair.go
  • server/runtime/compaction_overflow_repair_test.go
  • server/runtime/compaction_persistence.go
  • server/runtime/compaction_runtime_state.go
  • server/runtime/compaction_trim_test.go
  • server/runtime/compaction_utils.go
  • server/runtime/engine.go
  • server/runtime/engine_message_ops.go
  • server/runtime/engine_part10_test.go
  • server/runtime/engine_part11_test.go
  • server/runtime/engine_part12_test.go
  • server/runtime/engine_part13_test.go
  • server/runtime/engine_part14_test.go
  • server/runtime/engine_part15_test.go
  • server/runtime/engine_part4_test.go
  • server/runtime/engine_part6_test.go
  • server/runtime/engine_part8_test.go
  • server/runtime/engine_part9_test.go
  • server/runtime/engine_reviewer_helpers.go
  • server/runtime/engine_state.go
  • server/runtime/engine_test.go
  • server/runtime/exclusive_step_test.go
  • server/runtime/goal.go
  • server/runtime/history_replacement.go
  • server/runtime/message_lifecycle.go
  • server/runtime/meta_context.go
  • server/runtime/meta_context_runtime.go
  • server/runtime/orchestration_collaborators.go
  • server/runtime/output_steering.go
  • server/runtime/prompt_cache_continuity_test.go
  • server/runtime/request_cache_lineage_part2_test.go
  • server/runtime/request_cache_lineage_test.go
  • server/runtime/reviewer_request_test.go
  • server/runtime/skills.go
  • server/runtime/state_stores_test.go
  • server/runtime/step_executor.go
  • server/runtime/subagents_test.go
  • server/runtime/token_usage_test.go
  • server/runtime/tool_executor.go
  • server/runtime/transcript_runtime_state.go
  • server/runtime/workflow_completion_test.go
  • server/runtime/worktree_reminder_test.go
  • server/runtimecontrol/service_test.go
  • server/runtimeview/projection_test.go
  • server/runtimeview/transcript_suffix_test.go
  • server/session/fileless_metadata_test.go
  • server/session/fork.go
  • server/session/runs.go
  • server/session/snapshot_test.go
  • server/session/store.go
  • server/session/store_part2_test.go
  • server/session/store_test.go
  • server/session/types.go
  • server/sessionlifecycle/service_test.go
  • server/sessionruntime/service.go
  • server/sessionview/dormant_cache_test.go
  • server/sessionview/service_test.go
  • server/sessionview/snapshot_parity_test.go
  • server/sessionview/transcript_suffix_test.go
  • server/tools/transcript_contracts.go
  • server/transport/gateway.go
  • server/transport/gateway_unary_handlers.go
  • server/transport/route_policy.go
  • server/workflowrunner/starter.go
  • server/workflowrunner/starter_test.go
  • server/workflowruntime/completion.go
  • server/workflowstore/runs.go
  • server/workflowstore/store.go
  • server/workflowsvc/service.go
  • server/workflowsvc/service_test.go
  • server/workflowview/service_test.go
  • shared/client/remote.go
  • shared/client/remote_rpc.go
  • shared/client/workflow.go
  • shared/protocol/handshake.go
  • shared/rpccontract/routes.go
  • shared/serverapi/workflow.go
  • shared/servicecontract/services.go
💤 Files with no reviewable changes (8)
  • server/runtime/orchestration_collaborators.go
  • server/runtime/transcript_runtime_state.go
  • server/runtime/state_stores_test.go
  • server/runtime/chat_store.go
  • server/metadata/sqlitegen/models.go
  • server/runtime/output_steering.go
  • server/metadata/queries.sql
  • server/launch/planner_test.go
✅ Files skipped from review due to trivial changes (11)
  • .claude/skills
  • CLAUDE.md
  • server/metadata/migrations/00032_drop_session_agents_injected.up.sql
  • server/workflowruntime/completion.go
  • server/sessionview/snapshot_parity_test.go
  • AGENTS.md
  • cli/app/ui_mode_flow_test.go
  • cli/app/session_lifecycle_test.go
  • prompts/system_prompt/harness_workflow_autonomy.md
  • server/workflowview/service_test.go
  • server/metadata/sqlitegen/queries.sql.go
🚧 Files skipped from review as they are similar to previous changes (14)
  • server/runtime/workflow_completion_test.go
  • server/runtime/meta_context_runtime.go
  • server/runtime/compaction_carryover.go
  • server/transport/gateway.go
  • server/runtime/compaction_overflow_repair.go
  • server/runtime/engine_reviewer_helpers.go
  • server/runtime/request_cache_lineage_test.go
  • server/runtime/goal.go
  • prompts/reviewer_system_prompt.md
  • server/runtime/compaction_utils.go
  • server/runtime/engine.go
  • server/tools/transcript_contracts.go
  • server/runtime/tool_executor.go
  • server/runtime/step_executor.go

Comment thread server/runtime/committed_transcript_events_test.go Outdated
Comment thread server/workflowrunner/starter.go
Nek-12 added 2 commits June 9, 2026 17:53
A fan-out compact_and_continue branch persists a fresh clone before the rest
of planSession runs, but StartWorkflowRun's cleanup hook only covers failures
after planSession returns. A failure in PlanSession/EnsureDurable left the
clone directory orphaned. Track the disposable clone and remove it on any
planning failure.
Ignoring the steer error let a steering failure surface as a misleading
downstream event-assertion mismatch instead of the real cause.

@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: e94431520b

ℹ️ 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 +251 to +252
data: {
...edge.data,

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 Clear stale route points when reconnecting edges

Fresh evidence since the previous thread: WorkflowGraphEdge renders workflowEdgePath, which uses data.routePoints whenever at least two points exist before falling back to React Flow's source/target Bezier, so spreading the old edge.data here preserves the old routed endpoints. When a dirty draft reconnects or re-targets an edge and ELK is still pending or fails, the visible path and hit target remain attached to the old endpoints even though source/target were updated; clear routePoints or recompute them when projecting endpoint-changing edges.

Useful? React with 👍 / 👎.

Comment on lines +155 to +156
if reusesExistingSession(input) {
return nil

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 Roll back reused-session setup mutations on failure

When this guard skips cleanup for reused sessions, failures after SetWorktreeReminderState succeeds but before the run is attached (for example UpdateSessionExecutionTargetByID or AttachRunSession) now leave the reused source session alive with its worktree-reminder generation reset for a run that never started. Reopening/continuing that prior node session can then inject a duplicate/stale worktree-mode reminder; for reused sessions, defer the mutation until setup is committed or restore the previous reminder state on these later setup errors.

Useful? React with 👍 / 👎.

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