Skip to content

Merge upstream orchestration V2 (#2829) into Circe - #39

Merged
Absterrg0 merged 880 commits into
mainfrom
feat/circe-orchestrator-v2
Sep 18, 2026
Merged

Absterrg0 merged 880 commits into
mainfrom
feat/circe-orchestrator-v2

Conversation

@Absterrg0

@Absterrg0 Absterrg0 commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

Stack

First checkpoint of the Circe overhaul. Merges upstream's orchestration V2 rewrite (pingdotgg/t3code#2829, 837 commits the fork lacked vs 354 fork commits, merge-base de37964) into the Circe fork.

What this brings

  • App Run separated from provider turns; only a root node completes a run.
  • ExecutionNode tree: tools, approvals, subagents, plans as one graph.
  • ContextTransfer / ContextHandoff primitives for forks, provider handoff, merge-back, subagents.
  • Provider capability system instead of provider-name branching.
  • Lazy fork resolution, turn-item projection, durable effect outbox.

Conflict resolution (164)

  • Circe identity preserved: ~/.circe data dir, circe binary/package names, CIRCE_ env vars, circe:// schemes.
  • Migration IDs 41-66 stay as shipped. V2's three new migrations register as 67-69 so shipped IDs never collide.
  • V2 engine logic wins for orchestration, provider, persistence, CLI, cloud, terminal, MCP, SSH, client-runtime.
  • Unions applied for composition roots (server.ts, ws.ts, binCli.ts) so Circe control/voice/task-desk/desktop-use layers stay wired.

Circe composition on V2

  • Circe routing rides on the V2 app thread as clientRouting, so live presentation and push delivery resolve the origin interaction without the legacy activity markers.
  • buildV2TurnPresentation projects completions from terminal provider turns.
  • ProjectionSnapshotQuery unions V2 projection threads into its shell and detail reads, so the Circe control layer sees V2-created threads.

Status

All CI checks green.

juliusmarminge and others added 30 commits September 16, 2026 23:45
Adapt grouped tool summaries and the floating working timer to V2 run, attempt, and queue state. Bring over the composer, keyboard, and disclosure transitions while retaining the V2 activity inspector and queue controls.

Keep OV2 web composer and grouping behavior intact; share only the existing command label parser with mobile.
Restores main features dropped by the policy replay: #8569 theme wiring,
settings search rework, #8803 workspace-mutation refresh (v2-adapted),
video + image previews (web and mobile, v2-adapted), #8862 Expo glass,
and the round's docs. Timeline thinking rows (#8984) stay on the v2
work-live system.

Co-Authored-By: Claude Fable 5 <[email protected]>
The v2 equivalents of main's #8984 and #8922: a "Working for ..." header
anchors the active run, the trailing live tool row survives between
actions in past tense instead of vanishing, and a shimmering Thinking
row marks reasoning gaps. During workspace preparation the header shows
"Setting up worktree..." (driven by the local dispatch flag or the v2
run's preparing status, so remote viewers see it too), the composer
footer span is gone, and draft promotion waits until the run starts or
startup fails instead of navigating mid-preparation.

Co-Authored-By: Claude Fable 5 <[email protected]>
Adopts the round's main features into the v2 architecture: the #9023
media rework (streamed videos, media-file assets, protocol-relative
links), #9098 shared live-activity row folded into the v2 working and
thinking rows, the #9084/#9078 Claude model catalog for v2 consumers,
a native #9005 OpenCode child-session abort in the v2 adapter, #9013's
landed LegendList patch, and per-environment sidebar provider entries.
For #8600 the server-side pieces land, but auto-settle evaluation stays
client-side (reading the new server-owned settings) until the v2
orchestrator grows its own settlement reactor; main's v1-only reactor
and coalescer additions are dropped with the rest of the v1 path.

Co-Authored-By: Claude Fable 5 <[email protected]>
…ator

Ports #8600's server-owned settlement to orchestration v2 instead of
keeping client-side evaluation. A ThreadSettlementService sweep runs at
startup, on auto-settle settings changes, and once per minute: it
evaluates inactivity and merged or closed pull requests over v2 thread
shells and dispatches the new guarded thread.auto-settle command, which
rejects threads that changed after the sweep's snapshot or carry any
explicit override, then reuses the orchestrator's settle lifecycle.
With the server deciding, the clients drop their effectiveSettled
evaluation and partition on the persisted settledOverride like main.

Co-Authored-By: Claude Fable 5 <[email protected]>
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).

Co-Authored-By: Claude Fable 5 <[email protected]>
Round 17 adopted main's #8850 ComposerBanner.Attachment (mx-auto plus the
standalone drawer-inset width) without main's matching mounts, so the
stash tab's ml-auto lost to the attachment's auto right margin and the
tab centered over the composer. Column now spans its attachments like
main does, the stash tab zeroes the right margin, and the stash menu
keeps the full dock width.

Co-Authored-By: Claude Fable 5 <[email protected]>
The branch had drifted from main's composer and work-log design in ways
unrelated to orchestration v2: a pre-revert "Working for" shoulder tab
on the composer (main reverted #8693 and re-landed #8734 without it),
an inline stash variant plus in-flow stash menu, expanded tool rows that
hid their icons, an unmounted woke-thread banner, a composer scroll
observer main never had, and a right-panel toggle that lost its
showRightPanelControl gate so it rendered twice with the panel open.

ChatComposer and its satellites now start from main's files with only
the v2 delta re-applied (dispatch modes, queued-message editing, runtime
request ids, response capability). Background tasks surface as a
ChatView banner in main's backgroundLiveness shape instead of a
composer tab. SimpleWorkEntryRow takes main's PlainWorkEntryRow body
with the V2ItemInspector kept behind the expander.

Co-Authored-By: Claude Fable 5 <[email protected]>
Renumbers the v2 migrations 044-052 to 045-053 behind main's
044_ClearAutomaticProjectModelDefaults, and adopts main's sticky
new-thread selection (#9164), local-only worktree bases in the v2 launch
path (#8751), the PR summary read for settlement (#9176), Claude per-cwd
skills (#9210), the provider editor redesign with the branch's dedicated
environment fields re-grafted (#8508), and the client half of
continue-threads-across-restart (#9167). The server-side continuation
markers stay unported: they live in the v1 session directory, and v2
recovery terminalizes running runs on restart, so the capability is
withheld until the v2 runtime carries them.

Co-Authored-By: Claude Fable 5 <[email protected]>
Index event sequence lookups, recover only threads with pending work, and page projection verification and rebuilds. Bound provider event logging and omit turn histories when resuming Codex threads.

Allow delegated thread identifiers through relay routes. Add focused regression coverage and document the performance constraints.
Retain main's composer, work-log, settings, mobile and performance changes through c8f77e0 while preserving v2 runs, queued messages, provider handoffs and durable history.

Port native compaction and logout, asynchronous Codex questions, provider usage accounting, automatic settlement and PR refresh into the v2 services. Bound live event retention during replay and delivery, measure thread replay before decoding, and read checkpoint metadata without loading transcripts or patches.

Keep main migrations through 047 and move the v2 migrations to 048–058. Preserve the existing branch history and the pre-rebase backup.

Model: GPT-6. Harness: Codex.
- Preserve Codex turn identity while suppressing duplicate diff notifications
- Optimize settlement projections and isolate thread visit handling
- Add concurrency and regression coverage across server and mobile
Restore the completed work timer divider and text size from main. Keep todo-list progress in the composer and omit it from web and mobile timeline entries, including completed task lists.

Verified pending, running, and completed task projection; 187 focused web tests and 35 mobile tests pass. Web and mobile typechecks pass.
Show Send when a running thread has draft content. Separate submission follow
from first-message anchoring so later sends do not reserve extra blank space.
Restore Android initial composer insets and iOS focus-aware dictation insets.

Keep opening and final assistant replies visible around completed folds,
anchoring Worked for at the first hidden item while preserving v2 relationship
cards and execution-attempt behavior.

Validation: 107 focused tests and the mobile typecheck pass. Formatting passes;
scoped lint and React Doctor report warnings but no errors. No simulator run.
Service Context tags across apps/server/src still carried upstream `t3/...`
keys while the package name makes the expected deterministic key
`@absterrg0/circe/...`. Re-keyed all 56 declarations, including the nine
orchestration-v2 services whose class-suffixed keys (e.g. `.../CommandPolicy/
CommandPolicyV2`) the prefix-only pass did not reach.

Also:
- Aligned persistence/Layers/Sqlite.ts with V2's node-only runtime. The
  merged file kept Circe's Bun/Node dynamic loader, but V2 removed the
  `@effect/sql-sqlite-bun` dependency, so the Bun branch could not resolve.
  `makeSetup(baseDir)` and the Circe `runMigrations({ baseDir })` signature
  are preserved.
- Removed a duplicate `export * from "./orchestration.ts"` in contracts.

apps/server typecheck: 832 -> 775 errors (runtime 87 -> 30). The remaining 30
are the Circe control/follow-up dispatch onto V2 commands, provider driver
interface drift, and binCli service context, all part of the next checkpoint.
V2 added generateStructured to the TextGeneration service; Pi and ACP Registry now return the same explicit unsupported error sibling drivers use, instead of omitting the method. Codex restored its Circe Schema.Constraint signatures against the V2 helper, so structured generation keeps its adapted codec. Removed terminal/BunPtyAdapter, which V2 replaced and nothing imports. apps/server runtime type errors drop 30 -> 18.
CirceController and CirceFollowUpDispatcher now dispatch through OrchestratorV2 instead of the V1 engine: message.dispatch with start_immediately/queue_after_active and deliveryIntent steer, runtime-request.respond for approvals and user input, thread.create, and run.interrupt against the resolved active run. Turn provenance uses V2's createdBy/creationSource on the command, not V1 thread.activity.append, which has no V2 equivalent. binCli no longer leaks V1 OrchestrationEngineService/ProjectionSnapshotQuery through CircePushNotificationsLive.

Removed V1-era tests that covered deleted code: server.test.ts, bin.test.ts, and orphanedProviderSessionStartup.integration.test.ts. No V1 orchestration source module is unreferenced yet, so none were deleted.

Verified: apps/server non-test runtime type errors 0 (from 18), test errors 173 (from 745), build:bundle exit 0.
controlTools declares every bounded tool with its host (node or client), risk, finite parameters, and acceptance speech, and gates what the classifier sees by what the host can execute. controlOutcome is the first-class outcome union (work, tool-answer, client-action, clarification, conversation, refused) that replaces the overloaded converse. controlDispatch is the single node executor table, where a missing executor is a wiring failure rather than a not-on-this-device refusal. @circe/core typechecks and its 10 tests pass.
Adds docs/internals/circe-decisions.md: naming and hard-cut choices, the CIRCE_* CI-secret exception, the decision to keep upstream's V1/V2 split and not port project commands to V2, the OrchestratorV2 dispatch mapping, turn provenance via command fields instead of activities, node-only SQLite, migration ID policy, and the control-layer design. Each entry notes the rejected alternative and the items left open for review.
controlClassify builds one decision request whose outcome question is a closed choice over work, conversation, refusal, clarification, and only the tools the host can execute, then composes exactly one CirceOutcome. The server dispatches each outcome: work through the OrchestratorV2 mapping, tool-answer through the node executor table, client-action as acceptance speech, clarification into durable typed frames, conversation as an inline answer, refusal explicitly. CirceController and CirceFollowUpDispatcher now run on this path, with CirceNodeTools providing weather and time executors from the existing quick lookup.

Verified: @circe/core typecheck green with 395 tests, apps/server runtime type errors 0 (12 total, all pre-existing test drift), build:bundle exit 0, the rebuilt Circe controller and follow-up tests 18/18.
Follow-up stop reports interrupted only when run.interrupt actually dispatched for a resolved run. Reroute with an active V1 source but no resolvable V2 run returns needs-input control-target-required instead of silently continuing. The classifier calls composeWorkOutcome only for the work outcome and otherwise refuses, applies the confidence floor to enum and text arguments so low-confidence answers clarify instead of guessing, and branches tool argument clarification on the unresolved parameter type.
@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
circe-web Skipped Skipped Sep 18, 2026 1:57pm UTC

Pass the resolved runtime-policy cwd into the Codex app-server spawn, so
relative provider writes land in the routed project instead of the server's
working directory. Remove a stray REMOTE_MUTATION.md that an earlier run
committed by mistake.
The Circe control layer reads threads via ProjectionSnapshotQuery, but its
shell list and thread-detail lookups only read the legacy projection_threads
table. V2-created threads live in orchestration_v2_projection_threads, so a
routed follow-up could not resolve its context thread and returned
context-thread-required.

Union the V2 projection threads into listActiveThreadRows and
getActiveThreadRowById, preferring V2 when a thread exists in both. Rename the
V2 thread-carrier field to clientRouting so the generic reactor stays free of
Circe concepts; the ownership guard now passes.
The third-party license plugin only recognized the @t3tools/ scope as
first-party, so the workspace @circe/core and @circe/client-runtime packages
failed the desktop build with an undeclared-license error. Recognize both
scopes.

Provide the voice and decision services the relay server group now requires in
its Api routing-fallback test.
The upstream merge left the web dialog and approval row on the pre-merge
fork behavior, so main's overlayElevation and approval-action tests failed.
Restore main's flat DIALOG_POPUP_CLASS, its non-media dialog variants, and the
inline compact approval row, dropping the fork-only glass dialog, media zoom
dialog, and overflow approval menu.

Keep the two shared media helpers wrapExpandedImageIndex and
buildAttachmentVideoPreview, and adapt the approval row to the V2
RuntimeRequestId plus the live-response capability, so the Circe control
center and composer keep working.
releaseReplayGate failed purely on its iteration counter, unlike every sibling
wait in the scenario harness, so a loaded runner burned the budget on idle
event-loop turns before the provider reached the gate. Honor the shared
wall-clock deadline too.

Give the ACP completed-root finalization test a 240s budget; it spawns a real
child process and shares its file with 100+ tests.
@Absterrg0
Absterrg0 marked this pull request as ready for review September 18, 2026 16:42
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 825e4893-7676-4c28-8dc5-828783698443


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.

@Absterrg0
Absterrg0 merged commit 4c5e7eb into main Sep 18, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants