Reaktor Agent Workspace
Reviewed 13 September 2026; third agent added 14 September 2026; the MCP door, the change budget and model traffic through Cloudflare AI Gateway added 30 September 2026. Reaktor should let a person build a new application, change an existing one, or perform an allowed application operation from either their own Codex/Claude session or the Reaktor desktop. A third agent, ChatGPT + Gemini, joined the pane on 14 September. The graph supplies application identity, contracts, dependencies, ownership and operations. Native harnesses supply coding, reasoning and their existing tools. The workspace connects them through shared tasks and verifiable evidence.
The objective is more accepted functionality for the same allowance and less human coordination, while preserving access to the strongest native capabilities. Reducing tokens is useful only when correctness, completion and human effort remain at least as good. Effort controls, context reuse, typed findings and selective collaboration are mechanisms to evaluate against that objective.
:::info Implementation boundary Single, Compare and Council already run through the shared local workspace. Desktop currently has Conversation, Team and Activity views, and as of 13 September it also selects reasoning effort and displays provider-surfaced reasoning. The interactive adapters landed on 13 September, and the bundle's MCP entry, the door, landed on 23 September. The bundle's skills and hooks, typed finding exchange, automatic graph context, routing policy, the change budget, model traffic through Cloudflare AI Gateway and the expanded workspace described below are proposed. Native API availability does not mean a feature is integrated. The status and delivery table identifies the evidence and remaining work. :::
1. Native capabilities and their qualification
The inspected baseline is Codex CLI 0.154.0 and Claude Code 2.1.270. The inventory comes from locally generated Codex App Server schemas and captured Claude CLI help; these are versioned observations, not a promise about every installation or model. Current official documentation was checked for the behavioral distinctions below.
| Capability | Inspected native surface | Reaktor consequence |
|---|---|---|
| Model and effort | Codex model/list, supportedReasoningEfforts, turn/start.effort; Claude --model, --effort | Expose each model's supported values without compressing them into a shared maximum |
| Service tier | Codex model service-tier metadata and thread settings | Keep speed/service tier distinct from model and reasoning effort; show availability and unknown pricing |
| Structured result | Codex turn/start.outputSchema; Claude --json-schema in print mode | Qualify a versioned findings schema and validate returned evidence references |
| Context delivery | Codex thread/inject_items; Claude prompt hooks and MCP resources | Record delivery boundaries; these mechanisms are not interchangeable |
| Continuation and branching | Codex thread start/resume/fork/revert/compact; Claude resume/fork controls | Preserve native sessions while the Reaktor task remains canonical |
| Live interaction | Codex turn start/steer/interrupt and server-originated requests; Claude streaming/control mechanisms | Build an interactive adapter with real reconnect, denial and stale-request tests |
| Usage and limits | Codex token-usage/rate-limit events and goal budgets; Claude result usage and print-mode limits | Keep usage, subscription allowance and API spend separate |
| Plans, changes and nested work | Codex plan/diff/item events; Claude tool and forwarded subagent events | Project provider events into artifacts with their original provenance |
| Extensions and configuration | Native MCP, skills, hooks, plugins and configuration surfaces | Install a scoped Reaktor extension while retaining the operator's setup |
| Execution context | Codex cwd and sandbox settings; Claude worktree and permission controls | Reuse native facilities, then qualify lease ownership and actual effect coverage |
App Server schemas expose both task controls and administration. For example, threadSection/* organizes threads into sections; it is not a conversation checkpoint API. A cwd selects a directory; it does not create or isolate a worktree. Provider rerouting events, where available, distinguish requested and observed models. These distinctions must survive the adapter.
The capability record needs independent facts: advertised by the installed version, configured for this principal/model, implemented by the adapter, and qualified by a named test. A schema-only feature stays experimental. Preserve bounded unknown events as provider extensions; do not turn them into commands or ordinary assistant text. Administrative operations such as changing account settings or installing plugins require their own user intent.
References: Codex App Server, Claude CLI reference. The local qualification record is named in §22.
2. Two entry points, one graph-owned workspace
Ship both an extension bundle and native session adapters. They serve different entry points to the same graph operations, tasks and evidence.
| Entry point | Experience | Reaktor owns |
|---|---|---|
| The person starts Codex or Claude directly | Their familiar harness can inspect and act on Reaktor through MCP, skills and hooks | Scoped graph access, operation preparation, receipts and task attachment |
| The person starts work in Reaktor | The desktop starts or attaches to a qualified native session, presents its requests and orchestrates participants | Task lifecycle, native adapter connections, event projection and orchestration |
The bundle has four parts: one MCP entry, task-oriented skills, hooks, and provider-specific role definitions where supported. The MCP entry has landed as the door; the skills, hooks and roles are proposed. Both harnesses can now carry all four in one native plugin: a Claude Code plugin bundles MCP servers, skills, hooks and sub-agents, and a Codex plugin bundles skills, MCP servers and hooks. Installation adds named entries without overwriting existing configuration. Uninstall removes only entries the bundle owns. Tools must report the selected workspace, principal and graph revision so an agent cannot accidentally operate on another open application.
A terminal session can use this bundle without opening a desktop window, but it still needs a local Reaktor owner. The door starts the workspace owner on its first call and finds a running kernel or desktop on loopback, so installing the entry is enough for a terminal session to reach Reaktor. Version negotiation and health reporting remain to be added. Several clients observe the same task; only the holder of its current execution lease dispatches work. Attaching to a user's independently running native session must use a supported mechanism, without silently taking control of it.
Keep the operator's installation, login, instructions, skills, MCP servers and chosen model. Reuse native editing, compaction, branching, subagents and sandbox facilities where they fit. Reaktor adds graph-specific coordination and evidence rather than implementing another coding harness. New model choices can arrive through discovery; new protocol behavior still needs adapter support and qualification before it becomes an enabled control.
Codex App Server is the target interactive transport. For Claude, qualify the native bidirectional control path and evaluate SDK use only with its actual authentication and entitlement requirements. A logged-in CLI is evidence for that CLI path, not proof that every SDK or API route uses the same subscription. Retain the existing subprocess adapters for batch work and explicitly display their interaction limits.
The door: one MCP entry in every harness
Landed 23 September. workspace install writes one MCP entry named reaktor into each harness it finds: a marked block in the project's .codex/config.toml for Codex, an entry in the project's .mcp.json for Claude Code, and an entry in ~/.gemini/config/mcp_config.json for Antigravity, which reads only a per-user file. Each entry launches the door over stdio with a seat label: codex, claude-code or gemini. The seat names the caller in logs and approvals. It is a label, and no credential stands behind it yet.
Behind the entry sit Reaktor's own servers and any number of third-party ones. The workspace owner starts on first use, and the kernel and desktop are found on loopback. Third-party servers come from a machine-wide provider list and an optional workspace list committed with the project. A workspace list is ignored until a person accepts its exact contents with workspace trust at a terminal, because a list inside a repository could otherwise mount a server on anyone who opens it. When the BestBuds workspace was verified, the door fronted 271 tools from 17 providers, among them Compose Hot Reload, Maestro, GitHub, Firebase, Google Cloud, Pencil and browser automation.
Landed 2 October: the complete cloud APIs. A fourth built-in provider, cloud, sits beside the
workspace owner, the kernel and the desktop. Its six tools search, describe and call every operation
in the API descriptions Cloudflare, Supabase and Google Cloud publish, about 17,000 in all, without
adding a tool per operation. Each tool carries its own safety class: searching and describing are
read-only, a read is a live read, and a write or a delete waits for an approval like any other
change. Reaktor Cloud lists the tools.
Reaktor's own servers apply their own rules. Every third-party call passes the door's policy:
- Each call is classified by effect. The default policy runs everything up to live reads without asking. Writes and destructive calls wait for a single-use approval that expires after 15 minutes, given at a terminal or in a macOS dialog. An unclassified call always asks. An answer given inside the agent's own conversation never counts as an approval.
- Results are scrubbed of credential-shaped text before they reach the model, and the call log records only a digest of each call's arguments.
- Credentials are named by where they live: an environment variable, a command such as
gh auth token, the keychain, or a file under the workspace'sconfig/or~/.reaktor/secrets. They are fetched when a call needs them and handed only to that provider's process or request. workspace verifyexercises every provider and every argument-free read through the real policy, so a broken provider is found before an agent trips over it.
One defect is open. The safety classes are ordered so that device writes sort below live reads, so a call classified as a device write, such as a Maestro tap, runs without asking even though the class is marked as needing approval.
The protocol each side speaks. Toward the harnesses the door speaks MCP over stdio. Codex initialises at protocol version 2025-06-18 by default and keeps 2026-07-28 behind a feature flag that is off, so the older version is what both harnesses meet today. Toward its providers the door negotiates per provider. An HTTP face for the 2026 protocol is not built.
Two Codex behaviours to design around. Codex waits one second (mcp_optional_startup_grace_ms) for optional servers when it builds its first tool list, and the door is a JVM process, so the Codex entry should be marked required or given a longer grace; the installer writes neither today. Codex also loads a project's .codex/config.toml only when the project is trusted, and ignores provider, notify and [otel] keys there, so model routing (§24) belongs in the user's config or a profile.
The size of the surface is now the main design problem. Every tool definition is a choice the model weighs on each turn and part of the prompt prefix it pays for, so tools are degrees of freedom in the sense of the change budget. Anthropic's tool-search documentation puts fifty tools at 10,000 to 20,000 tokens of context and reports that tool selection degrades beyond thirty to fifty loaded tools. Claude Code defers MCP tool definitions behind tool search by default, which hides most of the cost. It turns that off when ANTHROPIC_BASE_URL points at a host other than Anthropic's, because most proxies drop the tool_reference blocks tool search needs. Routing Claude Code through a gateway therefore loads every door tool on every turn, unless the gateway is qualified to forward those blocks and ENABLE_TOOL_SEARCH=true is set. Codex has no deferral and filters a server's tools with enabled_tools and disabled_tools. So the door should expose Reaktor's own verbs by default and mount third-party providers through per-task profiles. A profile is a provider list narrowed to the task class, and the full list stays one command away.
Hooks carry the change budget into the harness. Both harnesses have a Stop hook that can refuse to stop and hand a reason back to the model. Claude Code continues the conversation with the reason, and Codex runs another turn with the reason as its prompt. The bundle's proposed Stop hook runs the task's acceptance evidence and the budget check through the door. It lets the session stop when both pass and otherwise returns the findings. A Codex hook handler can be an MCP tool call, so there it is the door's check tool with no script in between. Hooks run only after the operator trusts them: Codex binds that trust to a hash of the hook, and Claude Code merges a plugin's hooks when the plugin is enabled.
What the door does not do yet. It has no HTTP face, so remote clients cannot reach it, and the ChatGPT seat reaches Reaktor through its own narrow connector (§23). It carries no caller identity beyond the seat label, so an approval is attributable to a seat and not to a principal. Graph operations stay off it: operation_plan prepares, and execution stays behind the kernel's reviewed path.
3. Effort without a lowest-common-denominator ceiling
AgentSpec now carries a first-class effort beside model, and the workspace discovers, validates, records and exposes it. What remains proposed here is per-turn override and routing policy; the field, its capability record and its desktop control have shipped.
Keep native values, scoped by provider and model. The inspected Claude help lists low, medium, high, xhigh and max; Codex advertises supported effort options per model. A shared enum that omits a level would unnecessarily limit the user. Proposed API sketch:
// Shipped in reaktor-conductor. TurnPolicy itself remains a sketch.
value class NativeEffort(val value: String)
data class EffortSupport(
// null means the set could not be enumerated, which is not the same as empty.
val supported: List<NativeEffort>? = null,
val default: NativeEffort? = null,
val source: String,
)
data class EffortRecord(
val requested: NativeEffort? = null,
val resolved: NativeEffort? = null,
val observed: NativeEffort? = null,
)
An enumerable set that rejects a request raises UnsupportedEffortException before dispatch. A set that cannot be enumerated accepts the value and records it as unverified. Neither CLI transport reports an effective effort, so observed is currently always null and the receipt says so rather than echoing what was sent.
Record requested, resolved and provider-observed values separately; if the provider does not report an effective value, leave it unknown. An unsupported explicit selection is an actionable error, not a silent downgrade. A user-selected routing profile may allow substitutions, but its mapping and limits must be visible before dispatch.
Effort is a quality, latency and consumption control whose effect depends on the task and model. Preserve provider defaults unless the user or an evaluated routing policy chooses otherwise. Avoid unnecessary configuration oscillation, but do not prohibit an authorized escalation to protect a cache. Some native settings persist to subsequent turns; the adapter must track this state instead of treating every override as one-turn-only.
4. Route from graph evidence and measured outcomes
Use deterministic graph signals to propose a task class and explain the choice. The classification remains uncertain when coverage is partial; a small known cone does not prove a small change.
| Signal | Starting point | Routing use |
|---|---|---|
| Declared dependents and touched modules | Gradle project edges and graph contracts | Estimate breadth; widen verification for incomplete coverage |
| Public contract or port changes | Authored module surfaces | Raise review requirements according to the project policy |
| Existing implementation pattern | Source lookup and retrieved precedent | Offer a constrained implementation profile; similarity alone is not proof of suitability |
| Concurrency, FFI or platform boundaries | Declared boundaries plus source evidence | Prefer stronger reasoning and target-specific checks |
| A failed check | Candidate-bound check result | Supply the failure to a repair attempt; distinguish code failure from infrastructure failure |
| Fully specified operation | Typed operation catalog | Execute directly once preconditions and existing authority permit |
| Prior accepted outcomes | Scoped run ledger | Evaluate whether a different model or effort improves cost, latency and completion |
The first implementation can use module-level signals; precise symbol impact, test coverage and learned routing remain separate deliverables. Start with a small explicit policy, show why it selected a profile, and let the user override it. Do not train a routing rule on a few successful anecdotes or lower effort solely because the model claims the task is easy.
For example, an already authorized deployment with a verified candidate and satisfied preconditions can be a deterministic operation. Deciding whether an unfamiliar candidate is ready to deploy may require substantial investigation. The execution command and the readiness decision are different costs.
5. Budgets and collaboration policies
Offer profiles built from three independent choices: reasoning/model policy, collaboration protocol and execution authority. A council is not merely a higher reasoning setting, and a small command vocabulary does not make the underlying planning problem easy.
| Work | Preferred starting mechanism | Escalation trigger |
|---|---|---|
| Exact query, known check or approved operation | Deterministic executor | Missing inputs, failed preconditions or an unexplained result |
| Log reduction and retrieval ranking | Deterministic parser first; qualified local model where useful | Unknown formats or lost diagnostic coverage |
| Implementation against known contracts | User/default implementation profile | Failed acceptance checks or discovered complexity |
| Novel design or difficult diagnosis | Strong reasoning profile | A concrete unresolved decision that benefits from independent analysis |
| Review or council | Independent findings, with an explicit decision to resolve | Conflicting evidence, not a desire to accumulate agreement |
A proposed RunBudget includes wall time, provider turns, token target, optional API cost cap, parallel slots and retry/escalation limits. Record the enforcement scope of every limit. A Codex goal token budget is not automatically a hard per-turn cutoff; a Claude print-mode dollar cap is not the user's remaining subscription allowance. Streaming usage can arrive late, and cancellation can leave an in-flight request billable. Forecasts must show that uncertainty.
Stop dispatching new stages when the applicable budget is exhausted, preserve partial findings, and reconcile active work. Retry transient failures differently from rejected designs. A configurable escalation limit can bound experiments; it must not introduce a universal “second failure means ask the person” rule. Continue authorized recovery when it can make progress within policy. Completion requires the agreed acceptance evidence, not participant consensus.
What a change may add
Proposed. A run budget limits what the work may consume, and a change budget limits what the result may add to the application: new concepts, public surface, parameters and flags, stored state and dependencies. Before the first edit, the task records its acceptance evidence and names the items its requirement needs. Everything unnamed is expected to be zero. The graph makes this checkable: the task's impact cone says which files belong to it, API and graph snapshots say what surface a candidate added, and reference counts say whether a new interface, factory or parameter has a second use.
The budget follows the task class of section 4. A bug fix names nothing. A feature names what its requirement names. A migration names the target mechanism and must delete the path it replaces, because leaving both doubles what a reader has to learn. A new framework primitive needs a second real use before its surface counts as required.
Three rules exist because an agent is rewarded for producing work:
- The implementing stage stops when the acceptance evidence passes. Anything else it noticed, such as a rename, a refactor or a neighbouring bug, goes into its report as a follow-up task.
- A trailing stage may only remove. It reads the change's own diff for code, wrappers, parameters and variation points that can go while the evidence stays green. Because it cannot add anything, it cannot turn into a second implementer.
- An item beyond the budget needs a reason that names a present requirement. The reason travels with the candidate as a typed finding (section 6).
The acceptance evidence is fixed before implementation for the same reason a validation set is chosen before training: evidence written after the code tends to fit the code. Candidates are then compared in order. Correctness and the requested behaviour come first and are never traded for simplicity. Among candidates that meet them, the one that adds the fewest new concepts, choices and dependencies wins, and length only breaks ties.
The same count explains the framework's design bar, which puts expressivity and composability above simplicity and one-shot or bloated APIs last. A composable primitive adds one concept whose parts stay independent. A one-shot API adds a concept for every behaviour, and a bloated API adds flags whose meanings interact.
6. Typed findings with semantic validation
Structured output lets both providers return a machine-readable final result. Qualify a shared schema subset, including refusal, invalid-output and truncation behavior. JSON shape validation is only the first check.
// Design sketch; references are resolved within the task's visibility scope.
data class Finding(
val id: FindingId,
val subject: SubjectRef,
val revision: String,
val claim: String,
val severity: Severity,
val failureScenario: String?,
val evidence: List<ArtifactRef>,
val proposedChange: PatchRef?,
val reportedConfidence: Confidence?,
val openQuestion: String?,
)
Resolve subjects and evidence against the visible graph and candidate revision. Record the producing participant, turn and schema version outside the model-controlled payload. A model's confidence is a claim, not acceptance evidence; a fabricated receipt cannot authorize an action. Missing or stale references become explicit validation findings.
Preserve competing findings rather than merging away dissent. Group by subject and comparable claim, retain alternative explanations, and let a targeted check resolve what it can. Free-text claims may need human or model interpretation; a typed envelope alone does not make semantic clustering deterministic.
Keep ThreadEvent.text alongside a versioned typed payload. Full transcripts remain available for inspection and recovery. Later participants can fetch selected findings instead of replaying every essay, but JSON is not inherently shorter than prose. Measure serialization size and downstream retrieval savings.
7. Context delivery, continuation and cache reuse
Compile a bounded context packet from the selected graph subjects, applicable decisions, candidate changes and recent evidence. Keep stable references and send deltas when the adapter supports them. Record what each participant actually received, including omissions and visibility restrictions.
Codex thread/inject_items persists appended items for subsequent model requests without starting a user turn. It does not make the injected text free to consume or guarantee that an in-flight request sees it immediately. Claude prompt hooks run at their documented boundary; an MCP resource is fetched when requested. Track delivery and consumption separately, with deduplication and a cursor. Keep retrieved evidence in an evidence channel; do not promote it into higher-priority instructions. Codex delivery semantics.
Within a compatible scope, order tool schemas and stable context deterministically. Cache reuse must never override visibility or revocation: hidden capabilities and private metadata may require a different schema surface. Record configuration changes, and measure provider cache hits rather than assuming how a harness rewrites its prefix. Claude's inspected cache-stability flag is a possible opt-in experiment, not a mandatory replacement for the operator's prompt configuration.
Current continuation is already intentional. CodexRuntime adds --ephemeral only when there is no resumed session and persistSession is false. Single-agent workspace turns request persistence. Compare/Council use fresh sessions and do not reuse peer-exposed sessions as later single-agent caches. Preserve that isolation rule. Forking or resuming may reuse context, but neither guarantees cached billing or a “delta-only” second run.
ContextPacket already has revision, freshness, partial, omitted-entry count and notices; entries have retrieval reasons. Add per-entry revision and size, entry-level truncation, and a retrieval deadline. Set partial when sources are omitted; do not conflate completeness with freshness. Ordinary inspection may proceed with an explicitly incomplete packet. Operations requiring current authority or specific evidence must wait for revalidation or fail with that missing prerequisite.
8. Local execution and honest isolation
Local execution and locally available data are the default for this plan. A cloud VM fleet is outside its delivery scope. Worktrees serve concurrent writers, clean baselines, reproducible checks and candidate review; they are useful even when only one agent writes.
WorkspaceMode is declared but is not yet an implemented checkout allocator. Current workspace collaboration rejects write-enabled submissions, and the workspace owner serializes writers against other active runs. That is coordination within this owner, not isolation from a person, another process, hooks or external MCP tools.
Use native worktree support where it fits and a local allocator where required. Codex's cwd points at the allocated checkout. Reaktor owns a lease, base revision, dirty-input policy, source-to-worktree mapping, resource namespaces, conflict detection and cleanup that preserves user changes. A linked Git worktree is not a process, credential, network or database sandbox.
Before enabling parallel writes, qualify same-file conflicts, cross-repository changes, restart recovery, branch cleanup and applying a candidate to a checkout that changed meanwhile. Until then, offer inspection collaboration with its coverage stated. Prompt blindness prevents peer text from entering the proposal prompt; it does not prevent inference from shared files, memory or external services. Evidence and memory namespaces need explicit isolation where independence matters.
Fan out only when units can progress independently and the latency or quality benefit justifies the extra turns. Avoid a fixed participant count or a universal claim that delegation saves tokens.
9. Artifacts from events and executors
Make reviewable artifacts the main presentation unit, building on the artifact workflow demonstrated by Antigravity. Reuse information already produced during the run and distinguish authored plans from observed results.
| Artifact | Source | What can be asserted |
|---|---|---|
| Plan | Provider plan items and task updates | The agent's proposed intent; rendering it needs no extra model call |
| Progress | Stage and attempt journal | Recorded state transitions, including blocked and interrupted work |
| Changes | Candidate diff against its base, reconciled with file events | Actual changed files at a named revision; tool names alone are insufficient |
| Check result | Build/test executor, exit status and parser | Checks observed for this candidate and environment |
| Preview evidence | Recorded browser actions and captured screenshots | What the configured verification flow exercised |
| Findings | Validated provider or deterministic analyzer output | Attributed claims with resolvable evidence |
| Operation receipt | Executor and reconciliation record | The operation's confirmed effects and any unknown outcome |
Rendering an existing model plan does not erase the tokens used to produce it. A deterministic browser flow can capture evidence without an extra model call; choosing a new flow or explaining its significance may require reasoning. Screenshots demonstrate observed behavior, not complete correctness.
Reduce large tool results before they enter model context. A CheckResult should retain command identity, candidate revision, environment, exit status, failure locations, parser version, coverage/truncation state and a reference to the full log. Unknown output formats fall back to bounded excerpts and a raw artifact. Deterministic reduction is reproducible, but is only as complete as its parser; do not call every reduction lossless.
10. Council independence and useful disagreement
The implemented council runs independent proposals, critique and synthesis. DefaultContextCompiler identifies peer material with agent IDs during critique; it does not implement anonymized ranking. Two providers produce a five-turn council before any additional verification turns. The current conductor may continue later rounds after a participant fails, though the workspace's final result remains failed.
Add optional anonymous proposal labels and typed ranking to the critique stage, following the mechanism in Karpathy's llm-council. Stable labels within a run can reduce explicit identity cues. They cannot guarantee anonymity: distinctive content, self-reference and shared context can reveal authorship. Preserve the original artifacts privately and test that participant-visible prompts contain no unintended identifying metadata.
Ranking is useful for comparing alternatives, but votes are not correctness evidence. A reviewer may abstain when proposals are incomplete or incomparable. The synthesis should cite accepted findings and unresolved dissent; a contested claim should route to a targeted check when possible. Make an extra ranking round optional because it adds turns; ranking within an existing critique response can avoid that extra round.
Keep successful stage artifacts after a failure. Fail-fast policy and selective stage retry remain planned and must preserve blind boundaries, prior evidence and budget accounting. Never reuse a participant's peer-exposed session as an independent proposal or ordinary single-agent continuation cache.
11. A readable trace with provider fidelity
AgentEvent now has Started, Delta, ToolUse, Reasoning and Finished. Claude's parser carries its thinking blocks — the payload is in thinking, not text, and the block signature is dropped rather than displayed — while codex exec --json was verified on 0.154.0 to emit no reasoning items at all, so that runtime reports Unavailable and emits nothing. Rich plans, request lifecycles and nested work still need a broader event model and the App Server transport.
Expose only content the provider makes available for display. Codex distinguishes summary events from model-dependent reasoning-text events; Claude thinking blocks must retain their actual provider classification. Do not relabel all thinking as a summary, synthesize unavailable private reasoning, or present any such text as proof of why the model acted. Default to concise public summaries, tools and evidence; unavailable reasoning is an ordinary state. Codex item event distinctions.
The proposed trace has four projections:
- Lanes: participants across stages, with role, requested/observed model, effort status, tools, usage freshness and pending requests.
- Divergence: agreed, contested and unique findings, linked to checks and with clustering uncertainty visible.
- Synthesis provenance: links from conclusions to findings, evidence and unresolved dissent. Missing attribution stays unknown rather than being inferred from nearby text.
- Participant context: the exact packet and peer labels that participant received, compared with the operator's attributed view.
Keep optional reasoning summaries collapsed. Scope, redact and retain trace artifacts according to their visibility policy. A trace is useful without reasoning text; plans, tool execution, questions, changes and checks are the essential evidence.
12. The task can orchestrate agents
Protocol.Planned currently obtains a TeamPlan once and executes it. The proposed orchestration loop can revise a plan through typed commands on the same graph-owned task. Task identity survives providers and attempts; native sessions attach to attempts rather than replacing that identity.
The command set should include Spawn, Steer, Queue, Attach, RunOperation, OpenStage, ResolveFinding, Interrupt and Close. Each command carries task/attempt scope, an idempotency key, the expected generation and relevant preconditions. The orchestrator proposes; validation, existing grants and the task actor decide whether it can execute. A typed RunOperation command cannot bypass operation preparation or confer authority.
Direct controls and explicit slash commands dispatch deterministically. A local classifier can suggest a command, but ambiguous natural language must not silently authorize an effect. Use a model for planning when needed, selecting its strength from task complexity and measured results. Coordinate checks and agents concurrently only when both refer to a compatible candidate revision.
| Composer mode | Target and behavior |
|---|---|
| Say | Addresses the orchestrator for the task; can propose a changed plan |
| Steer | Addresses one active participant and requires its expected turn ID; stale steering is rejected |
| Queue | Becomes that participant's next input after its current turn |
| Interject | Adds an attributed note to the task journal; does not imply model delivery |
Show the target and mode beside the send control. Stop applies to the selected participant or explicitly selected whole run. A global pending-request inbox brings questions and approval requests forward without hiding their scope.
Support deterministic check executors as participants, a temporary adversarial review stage, forks for alternative designs, and evidence-driven resolution of disagreements. Preview estimated provider turns before a council. None of these mechanisms requires a permanently cheap orchestrator or a fixed architect/executor assignment.
13. A small, schema-first graph surface
Pencil's integration demonstrates the two entry points: integrated agents and external MCP clients accessing a structured document. Adopt discoverable state and validated operations for Reaktor's graph. Keep the graph central; there is no need for a graph-agnostic control layer.
The existing desktop snapshot tools remain useful for inspection, and the shared workspace MCP already handles task submissions; both now reach agents through the door. Extend them with focused retrieval and execution rather than requiring a topology dump for every question. The proposed vocabulary sits over rgp/1:
| Verb | Contract |
|---|---|
describe | Versioned graph/query/operation schemas and capabilities visible to this principal |
query | Bounded subject, dependency, ownership, decision and evidence queries with coverage and freshness |
fetch | Page a referenced artifact with a size budget and scope check |
prepare | Validate a proposed operation and return a fingerprinted plan with required/effective grants |
execute | Revalidate and run that plan using an idempotency key; reconcile and return a receipt |
observe | Read or subscribe from a cursor without acquiring execution ownership |
Keep semantic subjects, runtime instances and source anchors distinct, with explicit mappings. The task itself is a graph subject with edges to goals, participants, candidates, checks and decisions. Large transcripts and logs remain referenced artifacts; a semantic graph node per text delta would add noise and storage overhead.
The same prepare/execute path must serve desktop, MCP and CLI. This is the path to complete control of exposed Reaktor operations. Arbitrary native shell or external tools remain outside that guarantee.
14. Routed permissions and actual coverage
Native provider requests, graph grants and operator consent are different facts. Route provider questions and approvals through the adapter without broadening the native policy. Apply existing user authorization to routine work; ask only when the requested action requires authority or a product decision that is still missing.
A pending request records provider request ID, task, attempt, scope, generation and expiry. A response must match that request and the current execution lease. Persist resolution so reconnects neither re-ask an answered request nor apply an old answer to new work. Account and configuration mutations are separate from task execution.
For graph operations, revalidate authority and preconditions at execution even if preparation succeeded earlier. Receipts distinguish requested policy, effective graph grants, provider tool policy, confirmed effects and uncovered paths. allowWrites=false is a request to the harness, not complete effect mediation. Unconstrained shell, hooks or external MCP servers can act outside Reaktor's operation router.
15. Measure accepted outcomes and human effort
The usage ledger should guide future routing as well as explain a completed run. Record task class, provider/model versions, requested and observed effort, cache state, token categories, wall time, tool-result bytes, packet size, retries, checks, acceptance and human interventions. Native subagent accounting and provider usage may be incomplete; mark missing coverage rather than entering zero.
Where traffic passes through Cloudflare AI Gateway, the gateway's per-request log is the collector for it (§24). Traffic that does not, such as Codex on a ChatGPT login and Antigravity, is reported only through the harness's own events and OpenTelemetry export, and each ledger row records which source it came from.
Use one normalization rule across providers: distinguish fresh input from cached input; cache-write tokens may be a subset of input, and reasoning tokens a subset of output. Do not add subsets twice. Record whether a report covers a turn or a cumulative session and avoid counting the cumulative total on every continuation. Subscription allowance is a separate measurement from estimated API dollars.
For the BestBuds/Reaktor workflow, the strongest hypotheses are less repeated repository discovery, fewer large build logs in prompts, reusable cross-module decisions, and fewer manually relayed instructions between providers. A council can increase consumption while improving a difficult decision; it is not automatically a token optimization.
No historical savings percentage or functionality multiplier has been established. Test matched tasks from the same revisions: cross-module implementation, failed-check diagnosis, a design disagreement, a mechanical change, and a greenfield vertical slice followed by a second feature. Record acceptance quality, defects, elapsed time and human minutes alongside tokens. Repeat enough cases to report variability and separate warm-cache from cold-cache results.
Report savings only against a comparable accepted baseline: (baseline consumption − integrated consumption) / baseline consumption. A functionality multiplier requires an equal-budget comparison of accepted outcomes of comparable difficulty. A shorter transcript or more lines of code is not that measurement. Count failed attempts, repair and model-assisted reduction in the denominator.
16. Local data with bounded retrieval
The hot path should answer exact identity, declared dependents, applicable decisions and recent check failures locally. Existing local source/module lookup and file-backed workspace records are the starting point. The full projection, journal and store integrations below are a target architecture, not a claim that every database is provisioned and synchronized on this machine.
| Store or view | Intended responsibility | Availability and authority |
|---|---|---|
| In-process source/module index | Exact lookup and declared dependency traversal | Local; report source revision and coarse/partial coverage |
| Symbol overlay | Syntax spans and supported semantic relationships | Derived and rebuildable; language-specific qualification |
| Local artifact cache | Source slices, diffs, logs, check results and screenshots | Paged by reference/digest with visibility checks and retention |
| Task journal | Ordered events, request resolutions, leases and checkpoints | Local task authority with explicit durability guarantees |
| Local PostgreSQL + pgvector | Scoped semantic precedent candidates | Optional accelerator; use lexical retrieval while embeddings or the store are unavailable |
| Local Memgraph projection | Relationship queries that benefit from indexed traversal | Optional, rebuildable projection; not a second semantic authority |
| Manna local read model | Scoped requirements, goals and decisions | Its owning source remains authoritative; writes revalidate there |
Add a local data profile with provisioning, migration/version checks, readiness, initial hydration, resnapshot and disk/retention controls. Download only selected, authorized datasets. A running database with an empty index does not satisfy readiness. Keep database services off the UI thread and keep inspection usable while a secondary store restarts.
Every projection carries its source cursor, revision, visibility scope, tombstones and explicit unknown-freshness state. Revocation must affect both retrieval and cached artifacts. Cache keys include workspace, principal visibility, source revision and embedding/index configuration. Stale search candidates may aid discovery; they cannot authorize a mutation or override an accepted decision.
Apply a retrieval deadline and return a truthful partial packet when optional enrichment misses it. Proposed targets to benchmark are warm exact lookups under 20 ms p50 and a bounded aggregate packet deadline; publish p95/p99 and cold-start results too. These are targets, not achieved measurements. Fresh authority-dependent operations retain their own required checks.
OpenAI's Habitat storage report describes centralizing routing, authorization and storage policy to avoid coordinating changes across many clients, while managing tail latency and downstream pressure. The design inference for Reaktor is to keep policy and storage bindings behind one versioned owner and make projections cheap to read locally. It does not justify copying a billion-user deployment topology or putting a remote service on every agent lookup. The Data Graph and Data Layer remain the owners of those contracts.
17. What Codex and Claude share
Share the graph-owned task, canonical journal, candidate identity, findings, evidence references and operation receipts. Each provider receives a context packet appropriate to its role and visibility. Provider sessions remain replaceable continuation caches.
Today the conductor compiles canonical history and context for native turns; typed artifact-only handoff is a future capability. Move toward a bounded handoff packet containing the goal, acceptance criteria, active decisions, unresolved findings, candidate changes and selected evidence. Preserve a cursor and fetch path to omitted conversation so nuance is recoverable. Receiving text still consumes input tokens even when it arrived by reference.
A useful acceptance flow is: Codex produces a finding, a Reaktor executor runs the relevant check, and Claude uses that finding and check result to repair the candidate. The desktop follows the same task throughout. Capture the packet actually sent, the full source artifacts and the acceptance result so this can be measured against manual handoff.
18. Manna's ownership boundary
When requirements, goals or decisions are Manna records, attach their identities and revisions to the task. Pull acceptance criteria from the owning obligation; retrieve decisions with applicability, acceptance and supersession so an old requirement does not silently return through search.
Agent findings can be stored as attributed proposals without asking a person to approve every record. Promotion to an accepted requirement or decision follows the owning source's policy and existing authorization. Where that policy requires human acceptance, show the concrete proposed change and its evidence. The model's confidence never supplies that authority.
Use a subscribed local read model for speed, with cursor recovery and visibility updates. If sync or authorization freshness is unknown, report it and restrict dependent actions appropriately. Manna, pgvector and Memgraph have different responsibilities; none replaces the task journal or the semantic graph's identity authority.
19. Mechanisms to adopt and qualify
These are source-backed design inputs, not a benchmark or an exclusivity claim.
| Source | Mechanism worth taking | Reaktor adaptation |
|---|---|---|
| Codex App Server | Persistent threads, structured events and interactive requests | Native interactive adapter with versioned qualification |
| Claude Code | Configurable native sessions, structured output and extension controls | Preserve the operator's harness and report transport-specific limits |
| Pencil | Integrated agents plus an external MCP surface for structured documents | Graph schema discovery, focused queries and validated operations |
| Antigravity artifacts | Plans, changes and browser evidence as review units | Project the task journal into reviewable artifacts with explicit provenance |
| Karpathy's llm-council | Anonymous peer labels, ranking and synthesis | Optional ranked critique, with independent acceptance checks |
| Aider repository map | Token-bounded, relevance-ranked source context | Seed retrieval from declared graph subjects and expand when coverage is incomplete |
| Tree-sitter | Incremental syntax trees | A rebuildable source overlay, with semantic precision qualified separately |
| LangGraph persistence | Checkpoints, durable state and resumable workflows | Explicit stage persistence and replay semantics in the graph-owned coordinator |
Adopt mechanisms that improve a tested Reaktor workflow. Adding another runtime or mirroring a competitor's entire feature list is not an acceptance criterion.
20. Source precision and durable execution
A derived symbol overlay
Combine authored contracts, ownership and ports with source-level evidence. Tree-sitter can incrementally extract syntax and symbol spans for supported grammars; syntactic references and call sites are candidates, not a complete resolved call graph. Overloads, dynamic dispatch, generated code and FFI may require compiler or language-server information. Qualify language coverage separately instead of promising precision across every language.
Attach known source symbols to existing semantic graph identities. Unmapped symbols still need revision-qualified source anchors; do not invent semantic ownership or merge source and runtime identities. Record extraction method, confidence and missing coverage. Seed retrieval from the declared dependency cone, then widen it when inferred links or unknown boundaries demand it. Declared edges are authoritative declarations, not proof that every implementation dependency has been declared.
The index can depend on parser bindings without making the semantic graph depend on tree-sitter. Measure incremental update cost and whether the overlay finds relevant changes missed by the module-level baseline.
Durability in the task owner
Adopt checkpoint and resume semantics from durable workflow systems while keeping Reaktor's task actor and graph identities canonical. Persist stage boundaries, attempt generations, request resolutions and typed reducers. Specify which events are durably acknowledged and which can be replayed after a crash; weaker persistence modes may lose recent progress.
A restored journal does not prove an external effect never occurred. Use executor idempotency keys where supported; otherwise reconcile an unknown outcome before retrying. Checkpoint tests must include crashes after an external success but before the local receipt is saved. “No duplicate effects” requires this executor contract, not merely a saved transcript.
Restore scopes stay separate: conversation, files/candidate, workflow state and external effects. An external deployment or sent message is not undone by reverting a thread. Native restore facilities should be reused with their actual coverage recorded.
An existing LangGraph agent could eventually participate through an adapter, but that is optional interoperability with packaging, authentication and lifecycle work to qualify. It is not a prerequisite for Codex/Claude integration, and the current RuntimeKind does not make a third runtime automatically available.
21. The greenfield and existing-app loops
Build the complete loop: describe → provision locally → author contracts → implement → preview → verify → review a candidate. The person should not have to assemble the steps or relay state between agents. Product comparisons should test this experience rather than assert that other builders cannot analyze dependencies or run regressions.
For a greenfield app, ask only for missing product choices that affect the result. Select a project profile and targets, create modules/contracts/ports/data shapes in the graph, provision the required local data, then implement a small vertical slice. Attach the candidate revision to build results, preview checks and acceptance evidence. Preview and deployment are distinct operations; use existing authorization and obtain any missing consequential authority against the concrete candidate.
The second feature is part of the acceptance test. Identify its declared impact and unknown coverage before editing, add it, and rerun checks that protect the first feature. Kotlin Multiplatform offers shared contracts across targets, but bindings and behavior still need target-specific qualification; one successful desktop preview does not prove mobile parity.
For an existing application, start from a selected graph subject or domain goal: inspect a failed run, change a feature, query permitted data, or execute a scoped operation. A client should be able to complete an allowed task using typed operations and a receipt without being granted general shell access. Developers may retain native shell tools, with that broader effect coverage visible.
The differentiation hypothesis is that declared structure plus owned verification makes later changes easier to assess. Measure first-candidate time, second-feature regressions, acceptance, consumption and human coordination. Do not substitute an unsupported “only Reaktor can do this” claim for that experiment.
22. Implementation evidence and delivery order
The baseline reviewed is Reaktor commit d2253293 and BestBuds commit e5d3a55c, plus the installed CLI inventory described in §1. Primary implementation files are AgentWorkspace.kt, AgentWorkspaceModel.kt, CodexRuntime.kt, ClaudeCodeRuntime.kt, ContextCompiler.kt and ContextPacket.kt under reaktor-conductor/src; desktop state and rendering live in AgentConversationState.kt and AgentConversationPane.kt under bestbuds/modules/engine/src.
| Area | Implemented baseline | Still proposed |
|---|---|---|
| Shared tasks | Local owner, canonical history, native continuation, idempotent submissions and restart recovery | Rich journal subscriptions, distributed attachment/lease recovery and typed evidence handoff |
| Collaboration | Single, two-provider Compare, five-turn Council; independent model choices; bounded participant output and usage aggregation; a three-seat council whose third seat is ChatGPT + Gemini | Anonymous ranked critique, selective stage retry and interactive orchestration |
| Third agent | ChatGPT + Gemini as a standalone provider and council seat: durable handoffs, source-bound imports, Gemini execution through Antigravity, live-qualified end to end; since 15 September ChatGPT drives the loop through a narrow MCP connector (§23) | Measured ChatGPT usage, a signed-in remote face in place of the secret URL, and automatic routing between pools |
| Desktop | Conversation, Team and Activity; task search, provider/model/effort selection, collapsed provider-surfaced reasoning, effort provenance in the receipt, pending requests with their scope and Approve/Deny where a session exists, cancellation and transcript | Full orchestration, changes/evidence, context, profiles and a cross-task request inbox |
| Native integration | Supervised CLI subprocesses; discovered capability records; first-class native effort; provider-classified reasoning events; interactive adapters for both harnesses — Codex over its App Server, Claude over stream-json stdin; conductor-held sessions, so a journalled request can be answered, steered or interrupted from the desktop and MCP; re-attachment to a run in flight | Structured results, the bundle's skills and hooks, the graph query/prepare/execute surface |
| MCP door | One reaktor entry per harness (Codex, Claude Code, Antigravity) over stdio; Reaktor's own servers plus trusted third-party providers; effect policy with single-use approvals; credentials by location; argument digests in the call log; workspace verify (§2) | Per-task tool profiles, the Codex required flag, caller identity beyond a seat label, an HTTP face for the 2026 protocol, the device-write ordering fix |
| Model egress | Nothing routes through AI Gateway; three BestBuds workers call Workers AI directly | One tagged gateway, the Claude Code subscription test, the ledger join, per-task spend limits and stored keys (§24) |
| Change policy | The policy agents follow is written into the repositories' agent guides | Budget check, stopping instruction, removal-only stage and Stop hook (§5) |
| Context and execution | Context packet shape, local source/module lookup, file-backed records and inspection collaboration | Automatic graph-selection context, full local projections and owned parallel worktrees |
Reduction is wired in, and execute is deliberately absent. check_result returns a finished run as typed diagnostics rather than its log: the control plane already holds every line a build printed, handing those to a model is the expensive way to say three things, and stripping them — which is what the safe read model did — says nothing at all. The run supplies what no parser can infer, so the result carries the sourceRevision it belongs to and says so when it has none rather than looking attributable. A sensitive run is summarised by its status alone: its output was withheld for a reason and a reducer is not an exemption, so a credential in withheld output never becomes a diagnostic that could be read.
prepare already existed as operation_plan — effect, allowed environments, approval requirements, whether it is executable now, and never starting anything — so it is named as such in graph_describe rather than duplicated under a second name. execute is not on this surface and the description says why: the kernel MCP is an unauthenticated loopback read endpoint, while operations carry approval requirements and confirmation phrases, and exposing execution there would put infrastructure behind nothing but localhost. That is an authentication decision rather than missing code, and it belongs to the operator.
The graph surface lives in the kernel, not the conductor. The conductor does not depend on the kernel and should not: it is the framework-side execution module, while the graph it would be querying belongs to the application. So graph_describe and graph_query were added to the kernel's own MCP. The bundle first installed the workspace and the kernel's graph as two separately named entries; since 23 September it installs one entry, the door, which reaches the kernel's graph on loopback.
graph_describe returns the surface version, the subject kinds it resolves and the queries it answers, so an agent learns the vocabulary once instead of requesting a topology per question. graph_query then answers one bounded question — subject, dependents, dependencies, impact, search — and the answer carries its own coverage and freshness. Truncation is stated rather than implied by a short list; an unresolved subject is reported as unresolved, which is a different fact from a subject that exists and has no dependents; and the impact walk tracks what it has seen, because a service-binding cycle is a configuration this repository can hold.
That surface is read-only by construction, and deliberately so. prepare and execute stay behind the kernel's reviewed planning path rather than being duplicated onto MCP: §13's separation of reads from writes is the point, and a query tool that could also mutate would have to be trusted rather than merely allowed.
Slice 2 is part-landed. workspace install writes a reaktor entry into the project's .codex/config.toml and .mcp.json, and into Antigravity's per-user configuration, so a terminal session reaches the workspace with no desktop open; workspace serve and workspace mcp were already the headless owner and its stdio bridge. The property the tests are about is not that the entry appears but that everything else survives: uninstall returns the Codex config byte for byte, including a neighbour's credentials and nested tables, someone else's MCP server is never removed, a .mcp.json the bundle created is deleted rather than left empty, and a harness that is not installed is skipped rather than having a config invented for it.
Typed CheckResult also landed. A reduction carries the command, exit status, addressable failures with file and position, the revision it belongs to — without which a green run cannot be told apart from a stale result for different code — and its own coverage, because a reduction that dropped a diagnostic and called itself complete is worse than none. Three judgements are pinned by tests against this project's real toolchain output: a build that warns and succeeds has not failed; a non-zero exit with no diagnostic is errored rather than passed; and Task X FAILED earns a failure entry only when nothing else explained why the build stopped.
Slice 1's gate is met. agent_attach returns a run's state, whether it is still executing, which participants hold a session that can be answered, and what it is blocked on. live and answerable are separate fields because they are separate facts: a run can still be executing while holding no session a client could answer through, and conflating them would offer controls that cannot work. Attaching is observation — it takes no execution lease and dispatches nothing — and a finished run attaches to its receipt rather than erroring, because a reconnecting client is asking what happened, not whether it is running.
Requests are now answerable. The Conductor hands the live session to its caller when a runtime has one, the workspace registers sessions per run, and agent_answer/agent_steer reach both MCP and the desktop. Three properties are tested rather than assumed: an answer is routed to the provider instead of recorded as an intention, so nothing is accepted in the journal that the provider never heard; a request that stopped being pending reports stale; and a run on the batch transport reports unsupported rather than accepting an answer nobody will act on. Sessions are dropped when their run ends, so a late answer cannot reach a finished turn.
An integration test drives the interactive pair through the shared workspace rather than standalone, which is what proves the workspace's continuation and capability reporting sit correctly on top of them: a turn reports its observed effort, a second turn on the same conversation keeps its context and reuses the same native session. It is opt-in behind REAKTOR_INTERACTIVE_WORKSPACE_TEST=1 and passes in about ten seconds of real provider time.
Both interactive adapters landed the same day and were qualified by driving the installed binaries, not by reading their schemas. Against codex app-server 0.154.0: thread/start reports the thread's effective model and reasoningEffort, so effort becomes an observed fact rather than an unverified request — the one question exec --json cannot answer; item/agentMessage/delta streams token by token; thread/tokenUsage/updated carries total and last breakdowns mid-turn; turns can be steered with an expected-turn precondition and interrupted. Against claude 2.1.270: --input-format stream-json keeps a session alive past result, and a control_request with subtype interrupt is answered with a control_response. Claude publishes no turn id, so its session numbers its own and says so rather than implying parity.
Both are reachable through AgentRuntimes.interactive; the shared workspace still defaults to AgentRuntimes.batch, because changing what the qualified Compare/Council path runs on needs its own evidence. Provider requests are journalled on the run and shown with their scope; answering them requires the conductor to hold the session, which is the remaining work in slice 1. Two opt-in live tests spend a real turn each, behind REAKTOR_CODEX_APPSERVER_TEST=1 and REAKTOR_CLAUDE_SESSION_TEST=1, and both pass. The conductor suite is 102 tests with no failures, plus four opt-in tests that spend real provider turns.
The effort and reasoning slice landed on 13 September in reaktor-conductor (Capability.kt, CliCapabilities.kt, both CLI runtimes, AgentWorkspace) and in the desktop pane. The conductor suite is now 79 tests with no failures and one existing opt-in test skipped; the desktop adds a capability-driven effort test and renders all three views at 1024×720 and 1280×900 against stated rather than probed capabilities. Two facts were established by running the installed CLIs, not by reading their schemas: codex exec --json emits no reasoning items at all, and Claude's thinking blocks carry their payload in a thinking field alongside a signature that is dropped rather than shown. Capability discovery is injectable, so no test depends on which harnesses the host has installed.
The recorded 13 September qualification ran 59 conductor tests: 58 passed and one existing opt-in test was skipped. Three targeted desktop tests passed, including all three current views at 1024×720 and 1280×900. Tests covered collaboration accounting, prompt visibility, persistence, unknown usage, idempotency, capacity, cancellation, failure propagation and interrupted-participant recovery. These are carried-forward results, not tests rerun by this documentation review.
A live Compare smoke test completed on both installed CLIs using the operator's configured models and authentication. Retrying the same request after owner restart returned the same receipt/session IDs without new model turns. Its prompt requested a short tabs invariant in an empty workspace without tools: it qualified transport wiring, not architecture quality or application building. The earlier tabs experiment separately exercised a live five-turn council.
The Compare run reported 2 provider turns; 35,368 inclusive input tokens, comprising 21,958 cached and 13,410 fresh; 7,898 cache-write tokens as an input subset; and 310 output tokens including 213 reasoning tokens. These are provider-reported counts, not a bill or a savings estimate. Evidence is retained in reaktor-conductor/experiments/agent-workspace-qualification-2026-09-13.md and tabs-council-2026-09-13.md.
Deliver in dependency order. Each slice should reach a real user flow; optional stores and advanced council features must not delay basic native integration.
| Slice | Deliverable and dependencies | Acceptance gate |
|---|---|---|
| 1 · Native session control | Complete, 13 September: capability record, first-class native effort, Codex App Server adapter, Claude bidirectional control path, request journal, answer/steer/interrupt over a held session, and re-attachment to a run in flight | Met. Start, continue, steer or explicitly report unsupported, stop, question, denial, reconnect and reject stale responses; operator configuration preserved and effective-value uncertainty recorded |
| 2 · Graph extension and evidence | Landed 13 September: installable bundle, writing named entries for two servers until 23 September and one door entry per harness since; headless owner and stdio bridge; graph_describe and graph_query; check_result returning a finished run as typed diagnostics bound to its candidate revision. prepare is operation_plan. Remaining: execute, which needs an authentication decision, not more code | Manually launched Codex and Claude use the same task and graph without a desktop window — met; uninstall preserves unrelated configuration — met, asserted byte for byte; revision-bound evidence for a run — met; executing an operation from the surface — deliberately not done, see below |
| 3 · Context and typed handoff | Bounded automatic graph context, structured findings, semantic validation and delivery cursors; depends on slices 1–2 | Codex finding → Reaktor check → Claude repair on one candidate; missing/stale evidence is rejected; interrupted delivery does not duplicate context; packet size and cache usage recorded |
| 4 · Review workspace | Artifact projections, pending-request inbox, native profiles, context inspector and compact companion; depends on journal/evidence | Complete one cross-module change from the pane; show changed files, actual checks, requested/observed settings and missing evidence without requiring transcript archaeology |
| 5 · Recovery and isolated candidates | Durable stages, reconciled retries, native restore mapping and local worktree leases | Crash around request resolution and external execution; reconcile unknown effects; reject stale generation; preserve dirty files and detect conflicts before enabling parallel writers |
| 6 · Orchestration and council | Typed commands, composer targeting, lanes/divergence, optional ranked critique and non-model check participants | Resolve a real design disagreement with cited evidence; maintain blind boundaries; stop only the selected scope; retry a failed stage without repeating confirmed effects |
| 7 · Evaluated routing and local enrichment | Ledger-backed routing, source overlay, local data profile and optional Manna/pgvector/Memgraph views | Matched accepted tasks show consumption, quality and human-time results; optional store outages do not block local inspection; visibility, tombstones and index rebuilds are tested |
| 8 · Complete product loops | Greenfield and existing-app flows assembled from the qualified slices | Build from an empty folder, add a second feature and verify the first; a scoped client operation completes with a receipt and no shell grant |
Desktop design contract
The six Pencil boards in bestbuds/modules/reaktor.pen are authored destination fixtures, not screenshots of shipped functionality. Their controls must be backed by the task model and qualified capabilities before becoming live. The existing Team and Activity views are the incremental starting point.
| View | Primary question | Model behind it |
|---|---|---|
| Conversation | What are we trying to do, and who receives this input? | Task goal, acceptance criteria, composer target/mode and canonical messages |
| Orchestration | Who is working, waiting or disagreeing? | Stages, participants, pending requests and findings |
| Changes and evidence | What changed and what verifies it? | Candidate diff, check results, preview artifacts and receipts |
| Agents and tools | What can this installed harness actually do? | Native configuration, capabilities, qualification and effect coverage |
| Context and memory | What did the agent see, and is it current? | Delivered packets, graph subjects, local projections and provenance |
Selecting a finding should reveal its graph subject, source anchor and evidence in the inspector. The compact companion and full workspace attach to the same task. Preserve selection and scroll position while events arrive; show unavailable controls with a specific reason; support keyboard navigation and useful narrow-pane layouts.






23. A third agent: ChatGPT + Gemini
The pane offers three agents: Codex, Claude Code and ChatGPT + Gemini. The third is one seat made of two halves — ordinary ChatGPT Chat plans and reviews, and Gemini executes through the installed Google Antigravity CLI. It exists because those are separate allowances from the Codex and Claude subscriptions, so a person whose usual agent is exhausted still has somewhere to work.
The planner half reaches Reaktor from ChatGPT's side. The OpenAI API is a different product from the ChatGPT subscription, so calling the API would not spend the allowance this seat exists to use, and ChatGPT chat has no outbound API that Reaktor could call. It does accept connectors, so since 15 September ChatGPT calls a deliberately narrow MCP connector: four verbs shaped as the loop (waiting tasks, packet, reply, await) and four read-only tools (read a file, search, list, and read the stored diff), served over Streamable HTTP and published through a Cloudflare tunnel. ChatGPT connectors accept OAuth or no authentication, so the connector's secret lives in its URL path. Copying the packet into ChatGPT by hand remains the fallback when the connector is off. Reaktor still cannot verify which entitlement answered or measure its tokens, and says so in every receipt; the run's own usage figures are Gemini's alone.
Two Cloudflare pieces could replace the secret in the path with a real sign-in, and both are proposals. An MCP server portal puts remote HTTP servers behind Cloudflare Access sign-in and can switch off or rename their tools. A Worker built on the Agents SDK's MCP handler with workers-oauth-provider can issue its own OAuth tokens and forward calls to the tunnel.
Everything around that transfer is ordinary durable work. A handoff carries the workspace root, the source revision it was built from, the graph subjects attached to the turn, and its phase and revision. An import must match all of them, so a reply written against source that has since moved is refused rather than silently applied. A real repository is rarely fully readable — vendored pods, APKs, design files and build outputs run past the source capture budget — so partial coverage is stated in the packet rather than used to refuse the turn: the revision still detects a changed or added file, and the packet lists what it could not read, including when that list is itself truncated. Imports are idempotent, importing never starts execution — agent_resume is the separate action — and a human review cannot turn a failed Gemini turn into a successful contribution. The three-seat council checkpoints the Codex and Claude stages before pausing, so a transfer does not cost their work.
Gemini's half is a real native turn: its own conversation id, native tool events, captured usage, and a source candidate with changed paths and a diff artifact. Reaktor asks for plan or accept-edits to separate inspecting from editing, which matters because Antigravity auto-allows writes inside the active workspace — the requested mode is the whole difference, so Reaktor does not send the flag that would make it inert. It is still a requested mode, not an OS sandbox.
Registration is per machine, not per project: agy reads one MCP configuration per user, so workspace install writes Reaktor's one entry, the door, to ~/.gemini/config/mcp_config.json without pinning a workspace, and it resolves the directory agy was started in. Antigravity then defaults mcp to Ask and a headless turn cannot answer a prompt, so install names the rule to allow, mcp(reaktor/*), rather than editing the operator's permission policy.
Compute pools in Settings pause or re-enable admission for the Codex, Claude, ordinary ChatGPT and Google pools. They are operator scheduling policy: pausing a pool stops new work and resumes from being admitted against it. They do not measure a balance, predict a reset, reroute a task or touch a call already running.
Qualified live against agy 1.2.2 on 14 September 2026: a real file read through the adapter, an editing turn that writes with the same inspecting turn refused, and the complete seat — plan transfer, Gemini execution with captured evidence, review transfer, completed run. Those tests spend the operator's Google allowance and run only under REAKTOR_GEMINI_LIVE=1. The council, handoff-binding and recovery properties are covered by offline tests that need no allowance at all.
24. Model traffic through Cloudflare AI Gateway
Status, 2 October 2026. Reaktor's own model calls can now go through AI Gateway. The conductor has a Gateway runtime: an open model on the workspace's Cloudflare account, reached through Cloudflare's REST inference API (/ai/v1/chat/completions), with confined read, search and list tools over the workspace. Each turn names AI Gateway reaktor in the cf-aig-gateway-id header when that gateway exists and the configured token can see it, tags the request with the agent, run and workspace, and records the route and the gateway log ids in the run. Without the gateway it calls Workers AI directly with the Wrangler sign-in. Hangar's AI pane reads the account's gateways, a week of gateway traffic and per-model Workers AI usage, and creates a gateway through an approved plan. The product workers below still call Workers AI directly, and AI.run still takes no gateway option.
Proposed. Nothing in the products routes through AI Gateway yet. The three BestBuds workers that use models, the bot and the two moderators, call the Workers AI binding directly, and reaktor-cloudflare's AI.run takes no gateway option. The proposal is one gateway as the egress for every model call Reaktor can route, so usage, cost, limits, keys and data-loss checks sit in one place that no single harness owns. AI Gateway does not carry MCP traffic, so it complements the door: the door governs tool calls and the gateway governs model calls.
The gateway is a new dependency, which the change budget prices highly. It earns its place by replacing four things Reaktor would otherwise build and run itself: per-provider usage collection, stored provider keys, rate and spend limits, and response caching. It also runs on the platform these repositories already deploy to.
What can route through it.
| Traffic | How it reaches the gateway | What pays |
|---|---|---|
| Reaktor's own model calls: orchestration commands, log reduction, planning drafts | the gateway's provider-specific endpoint, or Cloudflare's REST API with a gateway id | API rates, with provider keys stored in the gateway |
| Product AI on Workers | the gateway option of the Workers AI binding, once AI.run accepts it | Workers AI or provider rates |
| Claude Code on a subscription | ANTHROPIC_BASE_URL set to the gateway's Anthropic endpoint, with no API key or auth token | the subscription, whose limits and billing still apply |
| Claude Code or Codex on API keys | Cloudflare's published recipes: Claude Code with the base URL and a gateway header; Codex through a profile whose custom provider points at the gateway's OpenAI endpoint | API rates; setting a key replaces the subscription for that session |
| Codex on a ChatGPT login | not expected to work, because the login's token belongs to the ChatGPT Codex backend and the gateway's OpenAI endpoint forwards to the API | the subscription, observed through Codex's own OpenTelemetry export |
The subscription row needs a live test before anything depends on it. Anthropic documents that a gateway must pass the anthropic-beta header through unchanged, or subscription requests fail with 401. Cloudflare documents that a provider credential sent with a request is forwarded unchanged, and says nothing about that header. The test is one real turn with the base URL set, comparing the gateway's log with the usage in Claude Code's own stream-json result. The same test settles whether tool search survives the gateway, since the door depends on it.
What the gateway gives the design.
- The ledger (§15). The gateway logs every request with its token counts, cost estimate, cache status, provider and model. A request can carry up to five metadata entries, and Reaktor uses them for task, run, seat, stage and task class, so gateway logs join Reaktor's ledger on the same identifiers. Runs the conductor starts set them per process, through
ANTHROPIC_CUSTOM_HEADERSfor Claude Code andenv_http_headersfor Codex. On a subscription, those per-request counts are the allowance consumption per task that the conductor doc says no headless invocation reports today. - Acceptance on the log. When a candidate is accepted or rejected, Reaktor records the outcome against the gateway log ids of its task, so cost per accepted change becomes a query. The binding's
patchLogcan store the outcome as feedback on the log itself. Whether that works on logs kept under the retention rules introduced on 24 September is unconfirmed, so Reaktor's own ledger holds the outcome first. - Spend limits at the egress. A gateway holds up to 20 dollar budgets, each scoped by provider, model or a metadata key, with one budget per value. A budget per task is therefore one gateway rule, which gives the run budget of §5 an enforcement point outside the harness. Codex has no dollar cap of its own. Enforcement lags slightly and bursts can overshoot, and §5 already requires recording each limit's enforcement scope.
- Keys held once. Provider keys live in the gateway's stored keys, so developer machines and agents hold only a Cloudflare token. That token covers the whole Cloudflare account and cannot be limited to one gateway, so it is a credential in its own right and is delivered the way the door delivers credentials.
- Data leaving the machine. DLP profiles can flag or block secrets in prompts. That matters here because BestBuds tracks its own credentials in
config/, and an agent that reads that directory can put a key into a prompt. Scanning requests keeps streaming intact, while scanning responses buffers them. Guardrails do not support streaming, so they stay on product traffic.cf-aig-collect-log-payload: falsekeeps a request's metadata and drops its prompt and response, which is the right default for product traffic that carries user data. - Caching for deterministic calls only. The cache matches exact requests and skips streamed responses by default, so an agent turn will almost never hit it. Log reduction and classification of the same input can.
- Fallbacks inside a declared profile. A dynamic route can fall back to another model, and §3 treats an unannounced substitution as an error. So a fallback exists only inside a routing profile the person selected, and the log records which model answered, so the receipt names it.
- Traces. A request can carry an OpenTelemetry trace id and parent span, so each model call appears inside its run's trace.
- Read back through the door. Cloudflare hosts a read-only AI Gateway MCP server that lists gateways and returns log details. Mounted as a door provider, it lets an agent see what its own task has spent before it asks for a second call.
Limits to design around.
- Logs are short-lived. An account whose first gateway is created after 24 September keeps logs for 3 days on the free plan and 7 days on the paid plan, so Reaktor copies what the ledger needs within that window, through the logs API, Logpush on a paid plan, or the OpenTelemetry export.
- Cloudflare's own credits carry a 5% fee and are limited to 200 requests a minute per gateway. Stored keys are exempt from that limit, and agent volumes can reach it, so API-key traffic uses stored keys with the fallback to credits turned off.
- Dynamic routes are reachable only through the
/compatendpoint with stored keys, and Cloudflare has deprecated that endpoint for single-model calls. Route-based fallbacks are therefore a later step. - The gateway decides where a request goes. The harness still decides which model is asked for.
Delivery order. First, one authenticated gateway with Reaktor's own model calls and the Workers AI binding routed through it and tagged; the binding change is one optional parameter on AI.run. Second, the live subscription test for Claude Code, including tool search. Third, the ledger join and the acceptance records. Fourth, a spend limit per task. Fifth, stored keys and the Codex profile for API-key runs.
Related
Conductor owns the execution module and protocol design. Reaktor Graph Protocol defines the shared surface. Data Graph and Data Layer own storage representations and authority. Workbench Layers and the desktop master plan own where the workspace renders.