Skip to content

fix(release): stop shipping FakeBackend and desktop E2E material in production artifacts - #3226

Merged
Astro-Han merged 3 commits into
mainfrom
fix/3211-fake-backend-out-of-release
Aug 19, 2026
Merged

fix(release): stop shipping FakeBackend and desktop E2E material in production artifacts#3226
Astro-Han merged 3 commits into
mainfrom
fix/3211-fake-backend-out-of-release

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

FakeBackend is a test backend, but it was wired as a first-class production surface and left the build inside the release artifacts. The normal Runtime Host composition registered it unconditionally (packages/runtime-host/src/server/execution-composition.ts:289), and the production candidate entry statically imported the Desktop E2E composition, so both the CLI tarball and the packaged Electron app carried a test backend plus the --desktop-e2e bootstrap.

This PR is the packaging half of #3211: get the test backend and the Desktop E2E bootstrap out of the production build graph and out of both artifacts, without weakening the rule that E2E must run through the real Runtime Host composition.

What changed

  • FakeBackend moves to @maka/runtime/test-only/fake-backend; DesktopE2eBackend and its composition move to packages/runtime-host/src/test-only/desktop-e2e-execution.ts, with a new test-only/execution-candidate-e2e-main.ts entry beside it.
  • The production candidate entry loses its E2E import, and --desktop-e2e disappears from the candidate CLI, the launcher, connect-or-spawn and the Desktop candidate manager. The entry module is now the switch: runtime-host-boot.ts resolves @maka/runtime-host/test-only/execution-candidate-e2e-main when isE2e, and the production entry otherwise.
  • The production composition no longer registers a fake backend. Every deterministic-backend consumer — Desktop E2E, the in-process composition tests, and the forked execution-host test fixture — now goes through the existing primaryBackendFactory seam, which is exactly the seam test(release): FakeBackend is a first-class BackendKind and desktop E2E material ships in release artifacts #3211 asked to preserve.
  • Release packaging drops test-only/ on both artifact paths, and packages/runtime/README.md records the convention.

Design decisions this PR commits to (issue items 1 and 4)

Test-only compile entry. A test-only/ source directory plus a ./test-only/* package export, extending the convention @maka/runtime already used for ./test-only/observation-text-reader. This was chosen over build-time exclusion or export conditions because it makes one fact — "no production module imports this" — checkable statically, from one directory name, on both artifact paths.

Release-exclusion verification, without building a release. Three static checks, no packing required:

  1. isMakaDevelopmentArtifact in scripts/release-cli-file-policy.mjs now rejects any test-only/ segment, with unit tests in scripts/release-cli-file-policy.test.mjs (run by npm run check:release). test-only is deliberately not added to DEVELOPMENT_DIRECTORIES, so a third-party package shipping a directory by that name is unaffected — there is a test for that too.
  2. The same predicate already gates validatePackedFiles in scripts/release-cli-package.mjs, so if the copy filter ever let such a file through, packing throws rather than shipping it. copyRuntimeDist drops the directory at copy time.
  3. apps/desktop/electron-builder.config.mjs gains '!**/test-only/**' beside the existing '!**/__tests__/**'.

The strongest guarantee is not a file filter, though: a new test in packages/runtime-host/src/__tests__/execution-candidate-main.test.ts walks the built module graph from the production candidate entry across all bundled @maka/* packages and fails if it can reach any test-only/ module. Even a stray byte in an artifact would now be unreachable code.

Design decided here, implemented in the follow-up (issue items 2 and 3)

'fake' stays in BackendKind in this PR. Removing it is a persistence and product-surface change, not a packaging one, and it is large enough to review separately. The decisions, so the follow-up does not re-litigate them:

Persistence compatibility (item 2). Verified: a stored backend: 'fake' is not tolerated by decode today. packages/storage/src/session-store.ts:1146 (isBackendKind) is a hard validator — narrowing the union there turns every legacy fake session into Invalid session header … malformed fields, i.e. an unreadable session, not a degraded one. packages/core/src/agent-run.ts:712 and packages/core/src/scheduled-task.ts:492 have the same shape. So the follow-up must split the two jobs 'fake' currently does: selecting a live backend factory, and tagging a retired legacy session. BackendKind (the live selector) narrows to 'ai-sdk'; the persisted header keeps a wider 'ai-sdk' | 'fake' type that decode still accepts and that resolves to no factory. No data migration — the product already treats these rows as retired (session-send-projection.ts:118fake_backend, stale-sessions.ts:27, search exclusion in thread-search.ts:171), and rewriting them to 'ai-sdk' would make dead sessions look sendable.

Unknown-provider fallback (item 3). packages/core/src/llm-connections.ts:375 currently returns 'fake' for an unknown or legacy providerType. That is a behavior change to make explicitly: backendKindOf will throw on an unrecognized provider rather than silently resolving a connection onto a test backend. Callers that need a non-throwing answer use the readiness projection, which already reports "not a real connection" without needing a backend kind. This is called out here so the follow-up PR carries it under its own heading.

Behavior change

A session or Automation persisted with backend: 'fake' no longer runs the test backend. The composition registers an explicit refusal at that kind instead, throwing the canonical NO_REAL_CONNECTION:fake_backend error, which parseNoRealConnectionError already turns into the copy both surfaces show for these rows: the task came from the retired local simulation, add a real model and start a new one.

An earlier revision of this PR left no factory at all there. That was wrong: the Desktop composer does gate these rows (sendBlocked reads a destructive sessionHealthNotice, raised by projectSessionSendOutcome for fake_backend), but that is a renderer gate, not an authority. maka run resumes an existing session through a readiness check that only inspects the connection catalog and never reads the session header's backend, and scheduled-task.ts:492 still accepts execution.backend: 'fake' in a persisted template — both reach activation directly, and would have surfaced a bare No backend factory registered for kind="fake".

Rewriting the durable header to 'ai-sdk' on the read path was the alternative and is worse: it destroys the fact that drives the correct copy, and leaves a session that looks runnable while its llmConnectionSlug still points at nothing, so the failure resurfaces later and less specifically.

Not in scope

  • apps/desktop/src/main/e2e-fixture* (the dev screenshot fixture and @maka/core/e2e-fixture schema) still ships in the asar. It is guarded — resolveE2eFixture throws when app.isPackaged — and removing it from the build graph means making main.ts load it dynamically, which is a desktop-startup refactor, not a packaging filter.
  • apps/desktop/src/main/chat-readiness.ts's assertSessionCanSend fake-rejection has no production caller (only errorMessage is imported, by main-window.ts). It is residue, not an active guard; it is not treated as one here and is left for the follow-up's cleanup.

Part of #3211

Verification

Built @maka/code-mode@maka/core@maka/storage@maka/mcp@maka/runtime@maka/runtime-host@maka/ui@maka/desktop from clean.

  • @maka/runtime-host full workspace suite: 979 passed, 0 failed (node --test --test-concurrency=4 "dist/**/*.test.js").
  • @maka/runtime affected files: 237 passed, 0 failed (fake-backend, session-manager, runtime-continuation-crash, stream-graph-coordinator).
  • npm run check:release: 30 passed, 0 failed, including the new test-only file-policy tests.
  • npm run lint, npm run format, and @maka/desktop's four-config typecheck all clean.
  • Desktop Playwright E2E, the paths that exercise the moved material: 19 passed across send-message, slash-command-menu, streaming-remount, composer-inline-completion, parent-session-deletion. slash-command-menu.spec.ts:34 ("compacts the active session") drives DesktopE2eBackend.compactHistory, so it proves the new E2E entry still reaches the real composition through primaryBackendFactory.

Module-graph evidence for the packaging claim, from the built dist:

production entry : {"size":622,"reached":[]}
e2e entry        : {"size":1,"reached":["test-only/execution-candidate-e2e-main.js"]}

622 modules reachable from execution-candidate-main.js, none of them test-only; the E2E entry is itself test-only, as expected. This is the assertion the new test makes.

The retired-backend refusal has a red-to-green regression test (a legacy fake-backend session is refused with the product reason, not a registry error): removing the registration makes it fail on No backend factory registered.

On "fails without it": the release-cli-file-policy tests do fail on main — the predicate did not reject test-only/ paths. The module-graph test is a forward guard rather than a red-to-green test: on main the same modules exist under different names, so the assertion it encodes ("the production entry cannot reach test-only material") only becomes expressible once the directory convention exists.

Not run locally: a full CLI npm pack and a full electron-builder pack. Both are CI-side, and the point of the file-policy unit tests plus the module-graph test is to catch a regression without them.

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code (Opus) — investigated the issue against current main, drafted the design above, wrote the implementation and the new tests, and ran the verification listed. The human contributor of record reviews the final diff and owns accuracy and provenance.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Problem solved

This PR prevents FakeBackend and Desktop E2E code from entering production artifacts.

It removes production --desktop-e2e handling and unconditional fake backend registration. Desktop E2E uses the real Runtime Host composition through primaryBackendFactory.

It moves test-only code under test-only/, updates package exports, excludes test-only files from CLI and Electron artifacts, and adds release-policy and production module-graph tests.

Persisted backend: 'fake' sessions now fail with the fake_backend product reason. Persistence cleanup remains follow-up work.

Source of truth and solution scope

The PR extends the existing Runtime Host composition. It keeps primaryBackendFactory as the test seam and does not create a second runtime composition.

The test-only E2E entrypoint provides a separate launch path for test execution. It still uses the real Runtime Host.

This is the smallest coherent solution shown by the diff. The added entrypoint and boundary checks are necessary to keep test-only code out of production artifacts.

Simplification opportunities

The diff removes obsolete production options, CLI validation, backend registration, E2E lifecycle branches, and production imports.

No further deletion is evident without weakening release-policy, module-graph, CLI, or E2E regression coverage.

Validation and risks

Reported validation includes affected builds, Runtime Host tests, Desktop E2E tests, release-policy tests, lint, formatting, type checks, diff checks, and whitespace checks.

CI passed packaging, Windows checks, recovery, and dependency-audit workflows. Windows packaging and release validation passed.

Full local CLI and Electron packaging were not run. A local macOS Electron package build was not performed. Required-check status is unverified here.

Concrete risks include:

  • Existing persisted backend: 'fake' sessions can fail.
  • The public export changes from ./fake-backend to ./test-only/fake-backend.
  • Release artifact contents change for test-only/ files.
  • Desktop E2E startup uses a new test-only entrypoint and argument path.

Complexity delta

The PR removes:

  • Production --desktop-e2e state and validation.
  • desktopE2e fields from startup inputs.
  • Production FakeBackend imports and registration.
  • Production E2E lifecycle branches.
  • Production backend-registry dependence for legacy fake sessions.

The PR adds:

  • A shared candidate bootstrap.
  • A test-only E2E entrypoint and package export.
  • Test-only release filtering.
  • A module-graph test that checks relative, package, side-effect, declaration, and literal dynamic imports.
  • Explicit primaryBackendFactory setup in affected tests.
  • Startup-attempt IDs and diagnostic state handling.

Production authorities, branches, and artifact reachability decrease. The public surface changes through the renamed test-only export. Test-maintenance burden increases through boundary and release checks, but these checks enforce the stated packaging constraint.

Overall maintenance complexity decreases. The added complexity is justified by release safety and regression coverage.

Review-relevant risks

The current diff shows effects on persistence compatibility, public package exports, release artifact contents, and Desktop E2E startup behavior. Material changes in these protected areas require independent human review under repository policy.

The person performing the merge reviews the final diff. A maintainer makes the final determination.

Walkthrough

Desktop E2E startup now uses a test-only entrypoint. Production runtime-host code no longer accepts --desktop-e2e or registers FakeBackend. Candidate startup diagnostics, package exports, tests, and release tooling now separate test-only modules from production artifacts.

Changes

Runtime and release isolation

Layer / File(s) Summary
Dedicated desktop E2E startup
apps/desktop/src/main/..., packages/runtime-host/src/{candidate-cli.ts,candidate-entry.ts,execution-candidate-main.ts,test-only/*}, packages/runtime-host/src/__tests__/*
Desktop E2E runs use a dedicated candidate entrypoint. Production candidate parsing and lifecycle handling no longer use desktopE2e.
Candidate startup diagnostics
packages/runtime-host/src/client/{launcher.ts,connect-or-spawn.ts}
Candidate launches carry startup attempt IDs. Election handling retains, selects, and clears startup failure diagnostics.
FakeBackend test seam
packages/runtime/src/{test-only/*,package.json,README.md}, packages/runtime-host/src/server/*, packages/runtime-host/src/__tests__/*, apps/desktop/e2e/*
FakeBackend uses a test-only export. Production composition rejects retired fake sessions. Tests inject FakeBackend through primaryBackendFactory and use ai-sdk session metadata.
Release artifact boundaries
apps/desktop/electron-builder.config.mjs, scripts/release-cli-*
Packaging and release filtering exclude Maka test-only files. Policy tests cover Maka paths, production candidate paths, third-party paths, and Windows-style paths.
Runtime validation updates
packages/runtime/src/__tests__/*, packages/runtime-host/src/__tests__/*
Tests validate structured checkpoint summaries and historical graph, epoch, tombstone, and selected-result behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 2200d

The PR changes production packaging and backend composition, with the supplied build, test, release-policy, lint, format, typecheck, and E2E checks passing; no actionable merge-blocking risk remains, aside from a trivial bounded diagnostics-cleanup follow-up.

Sequence Diagram(s)

sequenceDiagram
  participant RuntimeHostBoot
  participant CandidateLauncher
  participant CandidateEntry
  participant RuntimeHostComposition
  RuntimeHostBoot->>CandidateLauncher: start candidate with startup attempt ID
  CandidateLauncher->>CandidateEntry: pass startup attempt ID
  CandidateEntry->>RuntimeHostComposition: start candidate composition
  RuntimeHostComposition-->>CandidateEntry: startup or lifecycle result
  CandidateEntry-->>CandidateLauncher: report startup failure or election result
Loading

Possibly related issues

  • maka-agent/maka-agent#3211 — The PR moves FakeBackend and desktop E2E execution behind test-only entrypoints and excludes them from production artifacts.

Possibly related PRs

Suggested reviewers: m4n5ter, uncertaintydeterminesyou4ndme

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: excluding FakeBackend and Desktop E2E material from production artifacts.
Description check ✅ Passed The description follows the template and documents the problem, changes, behavior impact, verification results, AI use, checklist, and remaining scope.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Ai Use Disclosure ✅ Passed The PR selects only substantive generative use, names Claude Code and its scope, and all 3 introduced commits have standalone Generated-by: Claude Code trailers.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/3211-fake-backend-out-of-release

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

@Astro-Han
Astro-Han marked this pull request as ready for review August 18, 2026 20:18
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Exclude test-only backends and E2E bootstrap from release artifacts

🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Isolates FakeBackend and Desktop E2E bootstrap behind test-only package entrypoints.
• Removes E2E flags and fake backend registration from production Runtime Host paths.
• Excludes test-only modules from CLI and Electron artifacts with static regression checks.
Diagram

graph TD
  A["Desktop Boot"] --> B{"E2E Mode?"}
  B -->|Production| C["Production Entry"] --> D["Runtime Composition"] --> E["AI SDK Backend"]
  B -->|E2E| F["E2E Entry"] --> G["FakeBackend Factory"] --> D
  H["Release Packaging"] -->|includes| C
  H -.->|excludes| F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Conditional dynamic import
  • ➕ Keeps a single candidate entrypoint.
  • ➕ Reduces duplicated startup lifecycle code.
  • ➖ Leaves test behavior encoded in the production entrypoint.
  • ➖ Makes static release-graph isolation harder to prove.
  • ➖ Risks bundlers retaining the dynamically referenced E2E modules.
2. Conditional package exports
  • ➕ Can hide test-only exports under production conditions.
  • ➕ Provides environment-specific module resolution.
  • ➖ Requires consistent condition support across Node, Electron, tests, and packaging.
  • ➖ Makes artifact contents dependent on build configuration rather than directory policy.
  • ➖ Creates a less visible boundary for production import reviews.

Recommendation: Keep the PR's separate test-only entrypoints and directory-based packaging policy. The approach makes production reachability statically verifiable, works consistently for CLI and Electron artifacts, and preserves realistic E2E coverage through the existing primaryBackendFactory seam.

Files changed (39) +295 / -146

Bug fix (10) +71 / -44
runtime-host-boot.tsSelect separate production and E2E candidate entries +8/-2

Select separate production and E2E candidate entries

• Resolves the test-only candidate entrypoint when running Desktop E2E and the production entrypoint otherwise. This replaces the former runtime flag switch.

apps/desktop/src/main/runtime-host-boot.ts

runtime-host-desktop-candidate.tsRemove the Desktop E2E candidate option +0/-2

Remove the Desktop E2E candidate option

• Removes desktopE2e from Desktop candidate startup inputs and stops forwarding it to connect-or-spawn.

apps/desktop/src/main/runtime-host-desktop-candidate.ts

candidate-cli.tsRetire the desktop-e2e production CLI flag +1/-11

Retire the desktop-e2e production CLI flag

• Removes desktopE2e parsing, validation, and result typing from the production Runtime Host candidate CLI.

packages/runtime-host/src/candidate-cli.ts

connect-or-spawn.tsStop forwarding Desktop E2E startup state +0/-2

Stop forwarding Desktop E2E startup state

• Removes desktopE2e from connect-or-spawn inputs and detached candidate launch requests.

packages/runtime-host/src/client/connect-or-spawn.ts

launcher.tsRemove the Desktop E2E process argument +0/-2

Remove the Desktop E2E process argument

• Drops the desktopE2e launcher option and no longer appends --desktop-e2e to candidate process arguments.

packages/runtime-host/src/client/launcher.ts

execution-candidate-main.tsMake the production candidate entry test-independent +2/-22

Make the production candidate entry test-independent

• Removes all Desktop E2E imports, branching, idle-grace overrides, and parent watchers from the production candidate bootstrap.

packages/runtime-host/src/execution-candidate-main.ts

execution-composition.tsRemove FakeBackend from production composition +0/-2

Remove FakeBackend from production composition

• Stops importing and unconditionally registering FakeBackend in the normal Runtime Host backend registry.

packages/runtime-host/src/server/execution-composition.ts

execution-candidate-e2e-main.tsAdd a dedicated Desktop E2E candidate bootstrap +48/-0

Add a dedicated Desktop E2E candidate bootstrap

• Introduces a test-only entrypoint that applies E2E idle timing, injects deterministic composition dependencies, watches the Desktop parent, and runs the standard host lifecycle.

packages/runtime-host/src/test-only/execution-candidate-e2e-main.ts

release-cli-file-policy.mjsReject Maka-owned test-only release files +6/-0

Reject Maka-owned test-only release files

• Extends the CLI artifact policy to classify test-only path segments as development artifacts while leaving third-party package policy unchanged.

scripts/release-cli-file-policy.mjs

release-cli-package.mjsSkip test-only directories during runtime packaging +6/-1

Skip test-only directories during runtime packaging

• Extends runtime distribution copying to omit test-only directories alongside test and fixture directories.

scripts/release-cli-package.mjs

Refactor (2) +5 / -5
desktop-e2e-execution.tsRelocate Desktop E2E composition under test-only +3/-3

Relocate Desktop E2E composition under test-only

• Updates the relocated E2E composition to import FakeBackend from its test-only export and fixes relative Runtime Host server imports.

packages/runtime-host/src/test-only/desktop-e2e-execution.ts

fake-backend.tsRelocate FakeBackend into the test-only source tree +2/-2

Relocate FakeBackend into the test-only source tree

• Places the deterministic backend under test-only and adjusts its imports to reference production runtime modules from the parent directory.

packages/runtime/src/test-only/fake-backend.ts

Tests (23) +206 / -93
composer-inline-completion.spec.tsImport E2E prompts from the test-only runtime export +1/-1

Import E2E prompts from the test-only runtime export

• Updates inline-completion E2E coverage to consume FakeBackend prompts through the explicitly test-only package path.

apps/desktop/e2e/composer-inline-completion.spec.ts

slash-command-menu.spec.tsUse the test-only FakeBackend prompt export +1/-1

Use the test-only FakeBackend prompt export

• Moves slash-command E2E prompt imports away from the retired production FakeBackend export.

apps/desktop/e2e/slash-command-menu.spec.ts

streaming-remount.spec.tsPoint streaming tests at test-only backend fixtures +1/-1

Point streaming tests at test-only backend fixtures

• Updates deterministic streaming prompt imports to the new test-only runtime subpath.

apps/desktop/e2e/streaming-remount.spec.ts

candidate-cli.test.tsVerify the retired E2E flag is rejected +6/-17

Verify the retired E2E flag is rejected

• Removes successful parsing coverage for --desktop-e2e and asserts that the production candidate CLI treats it as unknown.

packages/runtime-host/src/tests/candidate-cli.test.ts

desktop-e2e-execution.test.tsImport Desktop E2E execution from test-only +1/-1

Import Desktop E2E execution from test-only

• Updates backend tests to reference the relocated Desktop E2E composition module.

packages/runtime-host/src/tests/desktop-e2e-execution.test.ts

execution-candidate-main.test.tsGuard the production candidate module graph +66/-2

Guard the production candidate module graph

• Updates invalid-argument expectations and adds a static import-graph traversal. The regression test asserts that the built production candidate cannot reach any test-only module.

packages/runtime-host/src/tests/execution-candidate-main.test.ts

execution-composition.test.tsInject FakeBackend through the production composition seam +18/-11

Inject FakeBackend through the production composition seam

• Changes test sessions to declare the real ai-sdk backend kind and supplies FakeBackend through primaryBackendFactory. This validates production composition without registering a fake backend globally.

packages/runtime-host/src/tests/execution-composition.test.ts

execution-host-message.test.tsUse test-only FakeBackend message fixtures +1/-1

Use test-only FakeBackend message fixtures

• Updates execution-host message tests to import deterministic prompts from the test-only runtime export.

packages/runtime-host/src/tests/execution-host-message.test.ts

execution-host-queue.test.tsUse test-only FakeBackend queue fixtures +1/-1

Use test-only FakeBackend queue fixtures

• Moves execution-host queue prompt imports to the dedicated test-only package path.

packages/runtime-host/src/tests/execution-host-queue.test.ts

execution-host-recovery.test.tsUse test-only FakeBackend recovery fixtures +1/-1

Use test-only FakeBackend recovery fixtures

• Updates recovery tests to consume FakeBackend prompts through the non-production export.

packages/runtime-host/src/tests/execution-host-recovery.test.ts

execution-host.test.tsUse the isolated FakeBackend test export +1/-1

Use the isolated FakeBackend test export

• Redirects execution-host test prompt imports to the new test-only subpath.

packages/runtime-host/src/tests/execution-host.test.ts

execution-host-suite.tsModel fixtures as ai-sdk sessions with an injected backend +5/-5

Model fixtures as ai-sdk sessions with an injected backend

• Updates execution fixtures to declare ai-sdk as their backend while registering FakeBackend under that production backend kind. Imports now use the test-only runtime export.

packages/runtime-host/src/tests/fixtures/execution-host-suite.ts

execution-host.tsInject FakeBackend into the forked host fixture +19/-5

Inject FakeBackend into the forked host fixture

• Overrides candidate composition creation to supply FakeBackend through primaryBackendFactory. The fixture therefore exercises the real composition without relying on production fake registration.

packages/runtime-host/src/tests/fixtures/execution-host.ts

goal-root-authority.test.tsImport goal test backend from test-only +1/-1

Import goal test backend from test-only

• Updates goal-root authority tests to use the relocated FakeBackend export.

packages/runtime-host/src/tests/goal-root-authority.test.ts

plan-two-client-uds.test.tsInject a deterministic backend into multi-client host tests +16/-4

Inject a deterministic backend into multi-client host tests

• Changes test sessions to ai-sdk and introduces a composition factory that supplies FakeBackend through primaryBackendFactory across host restarts.

packages/runtime-host/src/tests/plan-two-client-uds.test.ts

root-turn-coordinator.test.tsUse test-only backend fixtures for turn coordination +1/-1

Use test-only backend fixtures for turn coordination

• Redirects FakeBackend and prompt imports to the isolated test-only runtime module.

packages/runtime-host/src/tests/root-turn-coordinator.test.ts

runtime-policy-coordinator.test.tsInject FakeBackend into runtime policy compositions +38/-26

Inject FakeBackend into runtime policy compositions

• Updates policy test sessions to ai-sdk and passes FakeBackend through primaryBackendFactory for each production composition instance.

packages/runtime-host/src/tests/runtime-policy-coordinator.test.ts

session-revision-two-client-uds.test.tsSeed revision tests with the production backend kind +9/-9

Seed revision tests with the production backend kind

• Moves prompt imports to test-only and changes seeded sessions and subagents from fake to ai-sdk, matching the injected deterministic backend path.

packages/runtime-host/src/tests/session-revision-two-client-uds.test.ts

fake-backend.test.tsUpdate FakeBackend unit-test imports +1/-1

Update FakeBackend unit-test imports

• Points direct FakeBackend tests at the relocated test-only source module.

packages/runtime/src/tests/fake-backend.test.ts

runtime-continuation-crash.test.tsUse the test-only backend in crash tests +1/-1

Use the test-only backend in crash tests

• Updates continuation crash coverage to import FakeBackend from its new test-only location.

packages/runtime/src/tests/runtime-continuation-crash.test.ts

session-manager.test.tsUse test-only backend fixtures in session tests +1/-1

Use test-only backend fixtures in session tests

• Redirects SessionManager's FakeBackend and deterministic prompt imports to the test-only module.

packages/runtime/src/tests/session-manager.test.ts

stream-graph-coordinator.test.tsUse test-only FakeBackend in graph tests +1/-1

Use test-only FakeBackend in graph tests

• Updates stream graph coordinator tests for the relocated deterministic backend.

packages/runtime/src/tests/stream-graph-coordinator.test.ts

release-cli-file-policy.test.mjsTest CLI exclusion of test-only modules +15/-0

Test CLI exclusion of test-only modules

• Adds cross-platform assertions that Maka test-only files are rejected and third-party test-only directories remain allowed.

scripts/release-cli-file-policy.test.mjs

Documentation (1) +1 / -1
README.mdDocument the test-only backend convention +1/-1

Document the test-only backend convention

• Clarifies that AiSdkBackend is shipped while FakeBackend lives under test-only, is excluded from releases, and must be injected through primaryBackendFactory.

packages/runtime/README.md

Other (3) +12 / -3
electron-builder.config.mjsExclude test-only modules from packaged Desktop apps +9/-1

Exclude test-only modules from packaged Desktop apps

• Adds an Electron Builder exclusion for every test-only directory, preventing FakeBackend and the E2E candidate bootstrap from entering app artifacts.

apps/desktop/electron-builder.config.mjs

package.jsonExport the test-only E2E candidate entrypoint +2/-1

Export the test-only E2E candidate entrypoint

• Adds a dedicated package export for the Desktop E2E candidate bootstrap under the test-only namespace.

packages/runtime-host/package.json

package.jsonMove FakeBackend to a test-only package export +1/-1

Move FakeBackend to a test-only package export

• Replaces the production FakeBackend subpath with @maka/runtime/test-only/fake-backend.

packages/runtime/package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d9ca0244-c1cc-4b53-8670-26df1fc37589

📥 Commits

Reviewing files that changed from the base of the PR and between 781fa8d and 836d976.

📒 Files selected for processing (39)
  • apps/desktop/e2e/composer-inline-completion.spec.ts
  • apps/desktop/e2e/slash-command-menu.spec.ts
  • apps/desktop/e2e/streaming-remount.spec.ts
  • apps/desktop/electron-builder.config.mjs
  • apps/desktop/src/main/runtime-host-boot.ts
  • apps/desktop/src/main/runtime-host-desktop-candidate.ts
  • packages/runtime-host/package.json
  • packages/runtime-host/src/__tests__/candidate-cli.test.ts
  • packages/runtime-host/src/__tests__/desktop-e2e-execution.test.ts
  • packages/runtime-host/src/__tests__/execution-candidate-main.test.ts
  • packages/runtime-host/src/__tests__/execution-composition.test.ts
  • packages/runtime-host/src/__tests__/execution-host-message.test.ts
  • packages/runtime-host/src/__tests__/execution-host-queue.test.ts
  • packages/runtime-host/src/__tests__/execution-host-recovery.test.ts
  • packages/runtime-host/src/__tests__/execution-host.test.ts
  • packages/runtime-host/src/__tests__/fixtures/execution-host-suite.ts
  • packages/runtime-host/src/__tests__/fixtures/execution-host.ts
  • packages/runtime-host/src/__tests__/goal-root-authority.test.ts
  • packages/runtime-host/src/__tests__/plan-two-client-uds.test.ts
  • packages/runtime-host/src/__tests__/root-turn-coordinator.test.ts
  • packages/runtime-host/src/__tests__/runtime-policy-coordinator.test.ts
  • packages/runtime-host/src/__tests__/session-revision-two-client-uds.test.ts
  • packages/runtime-host/src/candidate-cli.ts
  • packages/runtime-host/src/client/connect-or-spawn.ts
  • packages/runtime-host/src/client/launcher.ts
  • packages/runtime-host/src/execution-candidate-main.ts
  • packages/runtime-host/src/server/execution-composition.ts
  • packages/runtime-host/src/test-only/desktop-e2e-execution.ts
  • packages/runtime-host/src/test-only/execution-candidate-e2e-main.ts
  • packages/runtime/README.md
  • packages/runtime/package.json
  • packages/runtime/src/__tests__/fake-backend.test.ts
  • packages/runtime/src/__tests__/runtime-continuation-crash.test.ts
  • packages/runtime/src/__tests__/session-manager.test.ts
  • packages/runtime/src/__tests__/stream-graph-coordinator.test.ts
  • packages/runtime/src/test-only/fake-backend.ts
  • scripts/release-cli-file-policy.mjs
  • scripts/release-cli-file-policy.test.mjs
  • scripts/release-cli-package.mjs
💤 Files with no reviewable changes (4)
  • packages/runtime-host/src/client/launcher.ts
  • packages/runtime-host/src/server/execution-composition.ts
  • apps/desktop/src/main/runtime-host-desktop-candidate.ts
  • packages/runtime-host/src/client/connect-or-spawn.ts

Included review availability: Your plan provides up to 3 included reviews per hour; 1 remains after this review.

@qodo-code-review

qodo-code-review Bot commented Aug 18, 2026

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Action required

1. Graph check misses dynamic imports ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
staticImportSpecifiers recognizes import declarations but skips import('…'), so a reachable
production module can dynamically import @maka/runtime/test-only/fake-backend while this test
still passes; release packaging then removes that target and the runtime import fails. This
contradicts the new check's stated guarantee that the production candidate cannot reach test-only
modules.
Code

packages/runtime-host/src/tests/execution-candidate-main.test.ts[R84-85]

+  for (const match of source.matchAll(
+    /(?:^|[\s;}])(?:import|export)\b[^'"();]*?from\s*['"]([^'"]+)['"]/g,
Relevance

●●● Strong

Accepted history favors structural import-closure guards; dynamic imports directly violate this
test’s stated packaging guarantee.

PR-#1734
PR-#2176

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The graph walker only follows values returned by staticImportSpecifiers; its first regex
explicitly excludes ( before from, and its second only matches side-effect import declarations,
so import('…') returns no specifier. The package exposes the fake backend under a /test-only/
target, while both release-copy paths remove test-only directories, making an undetected dynamic
import a reproducible missing-module failure in an artifact.

packages/runtime-host/src/tests/execution-candidate-main.test.ts[38-66]
packages/runtime-host/src/tests/execution-candidate-main.test.ts[82-92]
packages/runtime/package.json[21-25]
scripts/release-cli-package.mjs[366-385]
apps/desktop/electron-builder.config.mjs[9-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The production module-graph check ignores string-literal dynamic imports such as `import('@maka/runtime/test-only/fake-backend')`. Such an import survives compilation, is omitted from the walk, and later fails because release packaging removes `test-only/`.

## Issue Context
Reuse and extend the existing `staticImportSpecifiers` scanner rather than adding a new policy, configuration, dependency, or public surface. Deletion or consolidation cannot satisfy the invariant because the scanner is the existing verification authority; the smallest correction is to recognize string-literal `import()` expressions and add a regression assertion.

## Fix Focus Areas
- packages/runtime-host/src/__tests__/execution-candidate-main.test.ts[82-92]

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


2. Legacy sessions lose backend ✓ Resolved 🐞 Bug ≡ Correctness
Description
Disposition: fix-now. Removing the fake factory makes any existing persisted session whose header
is backend: 'fake' fail with No backend factory registered for kind="fake" when it next starts a
parent or child turn, because activation dispatches using the durable header value without a
migration or fallback.
Code

packages/runtime-host/src/server/execution-composition.ts[289]

-    backends.register('fake', (backendContext) => new FakeBackend(backendContext));
Relevance

●●● Strong

Recent precedents accept preserving persisted compatibility when migrations or legacy durable values
would otherwise fail at runtime.

PR-#2102
PR-#2263

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR deletes the only production fake registration, but persisted headers may still legally
carry that kind and runtime activation uses it directly for factory lookup.

packages/runtime-host/src/server/execution-composition.ts[287-288]
packages/core/src/session.ts[262-262]
packages/storage/src/session-store.ts[1146-1148]
packages/runtime/src/session-manager.ts[771-781]
packages/runtime/src/runtime-kernel.ts[2819-2828]
packages/runtime/src/runtime-kernel.ts[2918-2926]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Dropping the `fake` registry breaks activation of persisted session headers that still store `backend: 'fake'`. Normalize those legacy headers to the supported `ai-sdk` backend through the existing durable-session migration/read path before they reach runtime activation, and add a recovery/activation regression test for a legacy header.

## Issue Context
`BackendKind` and storage validation still accept `fake`, while `BackendRegistry.build()` performs an exact kind lookup. Re-registering the fake backend is not an acceptable remedy because it would reintroduce test-only code into the production composition and release graph.

## Fix Focus Areas
- packages/runtime-host/src/server/execution-composition.ts[287-288]
- packages/storage/src/session-store.ts[1146-1148]
- packages/runtime/src/session-manager.ts[771-781]

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


Grey Divider

Context sources
Review mode: 🧠 Deep: This packaging and runtime-composition change spans multiple independent entrypoints, artifact filters, backend seams, and E2E/test paths, creating a dense set of easy-to-miss regressions in shipped behavior and release isolation.

Grey Divider

Tip of the day
💡 Did you know, you can show, collapse, or hide each part of a finding: code, evidence, and all

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread packages/runtime-host/src/server/execution-composition.ts
@YayoiNanoka

Copy link
Copy Markdown
Contributor

PR Assessment

What problem does this PR solve?

This PR removes FakeBackend and the Desktop E2E bootstrap from production module graphs and release artifacts, while preserving the existing Runtime Host composition as the E2E execution path.

It also replaces the old production --desktop-e2e switch with a dedicated test-only candidate entrypoint and gives persisted legacy backend: 'fake' sessions an explicit product-level refusal instead of an unregistered-backend error.

How does this PR solve the problem?

  • Moves FakeBackend and Desktop E2E composition code under test-only/ exports.
  • Removes the unconditional fake backend registration and the production --desktop-e2e CLI flow.
  • Selects the E2E candidate entrypoint from runtime-host-boot.ts, while the production candidate remains free of E2E imports.
  • Keeps deterministic tests and Desktop E2E on the existing primaryBackendFactory seam.
  • Excludes test-only/ files from CLI and Electron release packaging.
  • Adds a production module-graph test that follows static imports, exports, side-effect imports, and literal dynamic imports.
  • Registers an explicit fake_backend refusal so legacy sessions receive the existing user-facing product reason.

Is the problem correctly defined?

Correct.

The PR addresses both sides of the release-isolation problem: preventing test-only code from entering production artifacts and ensuring that removing the production fake backend does not degrade legacy persisted sessions into an internal registry error.

Principle-based assessment

  • First principles: The production artifact must not depend on test-only modules, and durable backend: 'fake' values must retain their retired-session semantics rather than being silently rewritten into a runnable backend. The implementation preserves both invariants.
  • Occam's razor: The PR removes the old production flag and import path, reuses the existing composition factory seam, and adds only the release filters and graph checks needed to enforce the boundary.
  • Minimal sufficient solution: The dedicated test-only entrypoint is sufficient to keep E2E behavior while removing the production E2E branch. The explicit legacy refusal avoids reintroducing FakeBackend or corrupting durable session metadata.

Review Findings

P1 Blocker

None.

P2 Should Fix

None.

Suggestion

None.

Verification

  • Base: 781fa8d18d7f1d5e983de8283b3e0a61cd05751d
  • Head: 2f4bb27ad8a3eee1e8afad13c79c75ab2fdf8ada
  • Executed:
    • Built @maka/code-mode, @maka/core, @maka/storage, @maka/mcp, @maka/runtime, and @maka/runtime-host.
    • Ran the affected Runtime Host candidate, composition, CLI, and Desktop E2E unit tests.
    • Runtime Host composition tests: 13 passed, 0 failed.
    • Candidate and Desktop E2E tests: 7 passed, 0 failed.
    • Release policy suite: 30 passed, 0 failed.
    • Checked the complete PR diff and verified no whitespace errors.
    • Checked GitHub Actions for the PR head: CI, Runtime Host tests, Desktop E2E, CLI package validation, Windows release checks, Windows recovery/baseline, and dependency audit all passed.
  • Key results: The production module graph reached no test-only/ module; the legacy fake-backend regression test returned the canonical fake_backend product reason; release packaging validation passed.
  • Temporary tests: Not created; no temporary files were committed or pushed.
  • Original workspace: Confirmed unchanged; the review ran in an isolated clone.
  • Not verified: A local macOS Electron package was not rebuilt separately, but the Windows packaging workflow and release validation workflow passed for this exact head.

Conclusion

Can merge.

The PR satisfies the stated packaging boundary, preserves the real Runtime Host composition for E2E, handles legacy fake sessions with an intentional product-level refusal, and has passing local and CI verification.

点击展开中文

PR 判断

这个 PR 解决了什么问题?

这个 PR 将 FakeBackend 和 Desktop E2E 启动代码从生产模块图和发布产物中移除,同时保留现有 Runtime Host composition 作为 E2E 的执行路径。

它还用独立的 test-only candidate entrypoint 替代了生产环境中的 --desktop-e2e 开关,并为持久化的旧 backend: 'fake' session 提供明确的产品级拒绝,避免出现未注册 backend 的内部错误。

这个 PR 如何解决这个问题?

  • FakeBackend 和 Desktop E2E composition 移到 test-only/ 导出路径。
  • 删除无条件的 fake backend 注册和生产环境的 --desktop-e2e CLI 流程。
  • runtime-host-boot.ts 中选择 E2E candidate entrypoint,使生产 candidate 不再导入 E2E 代码。
  • 测试和 Desktop E2E 继续使用现有的 primaryBackendFactory seam 注入确定性 backend。
  • CLI 和 Electron 发布打包都排除 test-only/ 文件。
  • 新增生产模块图测试,覆盖静态 import、export、side-effect import 和字面量动态 import。
  • 注册明确的 fake_backend 拒绝逻辑,使旧 session 得到现有的用户可理解错误原因。

这个问题定义得对吗?

正确。

这个 PR 同时处理了发布隔离问题的两面:防止 test-only 代码进入生产产物,并确保删除生产 fake backend 后,旧的持久化 session 不会退化成内部 registry 错误。

原则性判断

  • 第一性原理:生产产物不能依赖 test-only 模块;持久化的 backend: 'fake' 必须保留其“已废弃 session”的语义,不能被静默改写成可运行 backend。实现满足这两个不变量。
  • 奥卡姆剃刀:PR 删除了旧的生产开关和导入路径,复用了现有 composition factory seam,只增加了维持边界所需的发布过滤和模块图检查。
  • 最小充分解:独立的 test-only entrypoint 足以保留 E2E 行为,同时移除生产 E2E 分支。显式拒绝旧 session 避免重新引入 FakeBackend,也避免破坏持久化 session 元数据。

Review Findings

P1 阻塞

无。

P2 应该改

无。

建议

无。

验证

  • Base:781fa8d18d7f1d5e983de8283b3e0a61cd05751d
  • Head:2f4bb27ad8a3eee1e8afad13c79c75ab2fdf8ada
  • 已执行:
    • 构建 @maka/code-mode@maka/core@maka/storage@maka/mcp@maka/runtime@maka/runtime-host
    • 运行 Runtime Host candidate、composition、CLI 和 Desktop E2E 相关测试。
    • Runtime Host composition 测试:13 passed, 0 failed
    • Candidate 和 Desktop E2E 测试:7 passed, 0 failed
    • 发布策略测试:30 passed, 0 failed
    • 检查完整 PR diff,并确认没有 whitespace error。
    • 检查 PR head 对应的 GitHub Actions:CI、Runtime Host 测试、Desktop E2E、CLI package validation、Windows 发布检查、Windows recovery/baseline 和 dependency audit 全部通过。
  • 关键结果:生产模块图没有到达任何 test-only/ 模块;旧 fake-backend session 的回归测试返回规范的 fake_backend 产品原因;发布打包验证通过。
  • 临时测试:未创建;没有临时文件被提交或推送。
  • 原始工作区:已确认未修改;审查在隔离 clone 中进行。
  • 未验证:没有单独在本地重新构建 macOS Electron 包,但对应 commit 的 Windows packaging 和 release validation workflow 已通过。

结论

可以合入。

这个 PR 满足发布边界要求,保留了真实 Runtime Host composition 作为 E2E 路径,对旧 fake session 提供了明确且有意设计的产品级拒绝,并且本地和 CI 验证均通过。

…roduction artifacts

FakeBackend is a test backend, but it was wired as a first-class production
surface and left the build inside the release artifacts: the normal Runtime Host
composition registered it unconditionally, and the production candidate entry
statically imported the Desktop E2E composition, so both the CLI tarball and the
packaged Electron app carried a test backend and the `--desktop-e2e` bootstrap.

Move both behind a `test-only/` directory convention and cut every production
import of them:

- `FakeBackend` moves to `@maka/runtime/test-only/fake-backend`.
- `DesktopE2eBackend` and its composition move to
  `packages/runtime-host/src/test-only/desktop-e2e-execution.ts`, with a new
  `test-only/execution-candidate-e2e-main.ts` entry beside it.
- The production candidate entry loses its E2E import, and the `--desktop-e2e`
  flag disappears from the candidate CLI, the launcher, connect-or-spawn and the
  Desktop candidate manager: the entry module is now the switch, and
  `runtime-host-boot.ts` picks it from `isE2e`.
- The production composition no longer registers a `fake` backend. Every
  deterministic-backend consumer — Desktop E2E, the in-process composition
  tests, and the forked `execution-host` test fixture — now goes through the
  existing `primaryBackendFactory` seam, so the E2E path still runs the real
  Runtime Host composition.

Release packaging drops `test-only/` on both artifact paths: the CLI release
copy filter and `isMakaDevelopmentArtifact` (which also fails the pack if such a
file ever escapes), and the Electron `files` list beside the existing
`!**/__tests__/**`. A new test walks the built module graph from the production
candidate entry and fails if it can reach any `test-only/` module.

`'fake'` remains in `BackendKind` for now; retiring the persisted value, the
unknown-provider fallback in `llm-connections.ts`, and the product-layer
special-cases is a follow-up so this change stays a packaging fix.

Part of #3211

Generated-by: Claude Code
…odule graph

The production-entry reachability walk only matched static `import`/`export …
from` forms, so a `import('./test-only/…')` edge would have been invisible to
it — and the built `dist` already contains literal dynamic imports (for example
`@maka/runtime`'s `model-adapter.js` and `@maka/storage`'s
`foreign-session-store.js`). The guard could therefore have passed while a
production module reached test-only material.

Generated-by: Claude Code
…duct reason

Dropping the `fake` registration left activation dispatching off a durable
header value with no factory behind it, so a session or Automation persisted by
an older build failed its next turn with `No backend factory registered for
kind="fake"`. The Desktop composer does gate these rows — `sendBlocked` reads a
destructive `sessionHealthNotice`, which `projectSessionSendOutcome` raises for
`fake_backend` — but that is a renderer gate, not an authority: `maka run`
resumes an existing session through a readiness check that only inspects the
connection catalog, and a persisted Automation template still accepts
`execution.backend: 'fake'`.

Register an explicit refusal where the test backend used to be. It throws the
canonical `NO_REAL_CONNECTION:fake_backend` error, which `parseNoRealConnectionError`
already turns into the copy both surfaces show for these rows: the task came
from the retired local simulation, add a real model and start a new one.

Rewriting the durable header to `ai-sdk` on the read path was the alternative
and is worse: it destroys the fact that drives that copy, and leaves a session
that looks runnable while its `llmConnectionSlug` still points at nothing, so
the failure would resurface later and less specifically.

Generated-by: Claude Code
@Astro-Han
Astro-Han force-pushed the fix/3211-fake-backend-out-of-release branch from 2f4bb27 to 2200d14 Compare August 19, 2026 11:39

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/runtime-host/src/client/connect-or-spawn.ts (1)

235-241: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Clean up orphaned attempt diagnostics on terminal returns. Retention is bounded to 32 files for 24 hours, but upgrade_required and blocked_by_residency can leave recorded failures, and deadline timeouts leave unregistered late reports.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 08699108-348e-4194-9f62-fcc634a7c4ce

📥 Commits

Reviewing files that changed from the base of the PR and between 4a19d4e and 2200d14.

📒 Files selected for processing (15)
  • packages/runtime-host/src/__tests__/candidate-cli.test.ts
  • packages/runtime-host/src/__tests__/desktop-e2e-execution.test.ts
  • packages/runtime-host/src/__tests__/execution-candidate-main.test.ts
  • packages/runtime-host/src/__tests__/execution-composition.test.ts
  • packages/runtime-host/src/candidate-cli.ts
  • packages/runtime-host/src/candidate-entry.ts
  • packages/runtime-host/src/client/connect-or-spawn.ts
  • packages/runtime-host/src/client/launcher.ts
  • packages/runtime-host/src/execution-candidate-main.ts
  • packages/runtime-host/src/server/execution-composition.ts
  • packages/runtime-host/src/test-only/desktop-e2e-execution.ts
  • packages/runtime-host/src/test-only/execution-candidate-e2e-main.ts
  • packages/runtime/package.json
  • packages/runtime/src/__tests__/session-manager.test.ts
  • packages/runtime/src/__tests__/stream-graph-coordinator.test.ts

Included review availability: Your plan provides up to 3 included reviews per hour; 2 remain after this review.

@Astro-Han
Astro-Han merged commit 7bb776b into main Aug 19, 2026
21 checks passed
Astro-Han added a commit that referenced this pull request Aug 19, 2026
`BackendKind` was doing two jobs: naming the backend a build may select,
and typing the backend value read back from durable state. The in-process
FakeBackend stopped shipping in #3226, so the first job narrows to
`'ai-sdk'`; the second becomes `PersistedBackendKind`, which still admits
`'fake'` and now types the session header, the session-catalog wire
projection, the run header, the Automation template, the workspace
defaults, and the backend registry that dispatches off them.

No data migration. Sessions, runs and Automations written by builds that
shipped FakeBackend keep `'fake'` on disk: narrowing the decode guards
would make those rows read back as malformed, and rewriting them to
`'ai-sdk'` would make an unrunnable task look runnable, since their
`llmConnectionSlug` still points at nothing. Activation already refuses
them with the product's `fake_backend` reason.

`backendKindOf` no longer answers `'fake'` for an unrecognized
`providerType` — it throws. That fallback was the last live producer of
the value, and there is no honest backend to name for a provider this
build cannot describe; the non-throwing question ("can this connection be
used?") is `isRealConnection` / `isConnectionReady`. With no provider
declaring `'fake'`, the former `isFakeBackend` collapses to "is this
providerType one the build knows", so it is named for what it tests.

The send projection's dead `slug === 'fake'` branches go with it: a
session carrying that slug is refused one line earlier by its backend, and
a connection carrying it is refused by the readiness gate.

Also deletes `apps/desktop/src/main/chat-readiness.ts`. Its send gate —
`requireReadyConnection`, `assertSessionCanSend`,
`ensureSessionCanSendOrRebind`, and a third copy of the Chinese connection
error copy — had no caller left once the gate moved to Runtime Host; the
only live import was the one-line `errorMessage` helper, now inlined at
its single use site.

Part of #3211

Generated-by: Claude Code
Astro-Han added a commit that referenced this pull request Aug 20, 2026
`BackendKind` was doing two jobs: naming the backend a build may select,
and typing the backend value read back from durable state. The in-process
FakeBackend stopped shipping in #3226, so the first job narrows to
`'ai-sdk'`; the second becomes `PersistedBackendKind`, which still admits
`'fake'` and now types the session header, the session-catalog wire
projection, the run header, the Automation template, the workspace
defaults, and the backend registry that dispatches off them.

No data migration. Sessions, runs and Automations written by builds that
shipped FakeBackend keep `'fake'` on disk: narrowing the decode guards
would make those rows read back as malformed, and rewriting them to
`'ai-sdk'` would make an unrunnable task look runnable, since their
`llmConnectionSlug` still points at nothing. Activation already refuses
them with the product's `fake_backend` reason.

`backendKindOf` no longer answers `'fake'` for an unrecognized
`providerType` — it throws. That fallback was the last live producer of
the value, and there is no honest backend to name for a provider this
build cannot describe; the non-throwing question ("can this connection be
used?") is `isRealConnection` / `isConnectionReady`. With no provider
declaring `'fake'`, the former `isFakeBackend` collapses to "is this
providerType one the build knows", so it is named for what it tests.

The send projection's dead `slug === 'fake'` branches go with it: a
session carrying that slug is refused one line earlier by its backend, and
a connection carrying it is refused by the readiness gate.

Also deletes `apps/desktop/src/main/chat-readiness.ts`. Its send gate —
`requireReadyConnection`, `assertSessionCanSend`,
`ensureSessionCanSendOrRebind`, and a third copy of the Chinese connection
error copy — had no caller left once the gate moved to Runtime Host; the
only live import was the one-line `errorMessage` helper, now inlined at
its single use site.

Part of #3211

Generated-by: Claude Code
Astro-Han added a commit that referenced this pull request Aug 20, 2026
`BackendKind` was doing two jobs: naming the backend a build may select,
and typing the backend value read back from durable state. The in-process
FakeBackend stopped shipping in #3226, so the first job narrows to
`'ai-sdk'`; the second becomes `PersistedBackendKind`, which still admits
`'fake'` and now types the session header, the session-catalog wire
projection, the run header, the Automation template, the workspace
defaults, and the backend registry that dispatches off them.

No data migration. Sessions, runs and Automations written by builds that
shipped FakeBackend keep `'fake'` on disk: narrowing the decode guards
would make those rows read back as malformed, and rewriting them to
`'ai-sdk'` would make an unrunnable task look runnable, since their
`llmConnectionSlug` still points at nothing. Activation already refuses
them with the product's `fake_backend` reason.

`backendKindOf` no longer answers `'fake'` for an unrecognized
`providerType` — it throws. That fallback was the last live producer of
the value, and there is no honest backend to name for a provider this
build cannot describe; the non-throwing question ("can this connection be
used?") is `isRealConnection` / `isConnectionReady`. With no provider
declaring `'fake'`, the former `isFakeBackend` collapses to "is this
providerType one the build knows", so it is named for what it tests.

The send projection's dead `slug === 'fake'` branches go with it: a
session carrying that slug is refused one line earlier by its backend, and
a connection carrying it is refused by the readiness gate.

Also deletes `apps/desktop/src/main/chat-readiness.ts`. Its send gate —
`requireReadyConnection`, `assertSessionCanSend`,
`ensureSessionCanSendOrRebind`, and a third copy of the Chinese connection
error copy — had no caller left once the gate moved to Runtime Host; the
only live import was the one-line `errorMessage` helper, now inlined at
its single use site.

Part of #3211

Generated-by: Claude Code
Astro-Han added a commit that referenced this pull request Aug 20, 2026
#3226 stopped shipping FakeBackend; this retires `'fake'` from the live surface.

The value carried three jobs: a selector for a runnable backend, a literal in durable records, and a sentinel meaning "not real / not known". #3226 killed the first. The second is permanent. This removes the third, so `'fake'` now appears only in decode guards and in the one function translating it to the `fake_backend` product reason.

- `BackendKind` narrows to `'ai-sdk'`; `PersistedBackendKind = BackendKind | 'fake'` types everything durable — session header and summary, catalog wire projection, run header, Automation template, workspace defaults, and the registry dispatching off them.
- No caller chooses a backend. `CreateSessionInput.backend` is deleted rather than narrowed: a live build has exactly one backend, so the field carried no choice, only the chance of writing the retired value. The store stamps every new header, and a session derived from an older one no longer inherits its backend.
- Two backend-kind guards go with it: the `sessions:create` IPC check, now unrepresentable, and the T1 tool-boundary gate on `header.backend` — that one was reachable, but all it withheld was the protocol marker on the initial event of a run that dies at `reserveRun` before any tool dispatch, and every marker consumer treats such a run the same as an unmarked one.
- No data migration. Legacy rows keep `'fake'` on disk. Narrowing the decode guards makes them read back as malformed; rewriting them to `'ai-sdk'` makes an unrunnable task look runnable, since `llmConnectionSlug` still points at nothing. Activation refuses them with the product reason, as of #3226.
- `backendKindOf` throws for an unrecognized `providerType` instead of answering `'fake'`. This changes `@maka/core`'s public contract; it has no in-repo caller.
- Provider recognition gets one own-property-safe owner, so inherited object members such as `__proto__` no longer read as registered providers.

Behavior change: `shouldRebindSessionToDefault` listed `fake_backend`, but nothing performs that rebind — activation dispatches off the header's own backend, so no connection swap could help. Removing it makes the projection answer `blocked`, lets the rail and the composer drop the workarounds that read `session.backend` directly, and surfaces the existing stale-task notice for unlocked rows.

Follow-up tracked in #3306.

Closes #3211

Generated-by: Claude Code
yihanzhu added a commit to yihanzhu/maka that referenced this pull request Aug 21, 2026
ScheduledTaskExecutionTemplate.backend is durable state nothing reads:
the fire path builds the execution session without it, and after apache#3249
session creation no longer accepts a backend from any caller. Drop the
field from the template, stop copying header.backend in
executionTemplateFromHeader (the writer that could freeze a legacy
'fake' into a new record, apache#3211), and stop emitting it from the
protocol decoder.

The execution decoder is a closed shape, so the key moves from the
required list to the optional one instead of disappearing: Automations
frozen by older builds still carry it and must stay decodable. It is
tolerated on the way in and never lands on the decoded value. No
migration, matching apache#3226 and apache#3249 for session headers.

Closes apache#3306

Generated-by: Claude Code (Fable 5)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants