Skip to content

refactor(daemon): add the single package entry and resolve its metadata consumers - #3633

Merged
thymikee merged 3 commits into
mainfrom
refactor/daemon-single-entry
Oct 15, 2026
Merged

thymikee merged 3 commits into
mainfrom
refactor/daemon-single-entry

Conversation

@thymikee

@thymikee thymikee commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Summary

Layer 2 of the daemon single-entrypoint stack (after #3616 and #3625): @agent-device/daemon gets its public API in one file, and the seven production subpaths collapse into it.

  • packages/daemon/src/index.ts is the package boundary: explicit named re-exports, no export *. The one value is startDaemonRuntime. The rest are types the composition and platform-runtime modules name (ComposeDaemonRuntimeDeps, DaemonRuntimeController, DaemonRuntimeDeps, DaemonRuntimeDepsInput, DaemonPlatformServices, PlatformOwnerLifecycle, PlatformResourceCleanup, DaemonRequest, DaemonInvokeFn).
  • exports drops ./server/daemon-runtime, ./platform-owner-lifecycle, ./platform-resource-cleanup, ./platform-services, ./daemon-request, ./daemon-command-registry and ./route-owner-files, and gains .. src/daemon.ts, src/daemon-composition.ts and src/platform-runtime-* import @agent-device/daemon.
  • Metadata consumers resolved at their owner:
    • route-owner-files was tooling metadata keyed by command-registry's own DaemonCommandRoute. It now sits beside the per-command claims in @agent-device/command-registry/owner-files (existing subpath). The scripts, the CLI command-explain test, command-surface-metadata, and owner-files-no-leak read it there, so none of them depend on the daemon.
    • daemon-command-registry stays daemon-owned: its queries take DaemonRequest, and ~50 daemon modules use them. Its outside consumers no longer need it. scripts/depgraph/affected-run.ts and command-descriptor-parity.test.ts read deriveDaemonCommandDescriptors(commandDescriptors). command-descriptor-ref-frame-effect.test.ts tests the daemon query, so it moved to packages/daemon/src/core/__tests__/ unchanged apart from its import.
    • The three daemon-client-abort*.test.ts files declare a local (req: DaemonWireRequest) => Promise<DaemonResponse> instead of importing DaemonInvokeFn.
  • R81 allows packages/daemon/src/index.ts as the one production file at the daemon root, with a test.
  • Eager closure: packages/daemon/src/index.ts is a new entry evaluating 372 modules, which is startDaemonRuntime's server graph. It carries an APPROVED_OVER_CEILING row (fix(metro): separate server control from Expo app launch #3352). src/daemon.ts and every existing entry stay under the no-growth rule. The stale maestro row is removed, because refactor(maestro): shape the replay backend as a create(host) plugin #3623 is now in the merge-base and the gate requires it.
  • Docs: ADR 0033's export-surface section describes the single entry. ADR 0019 notes that DaemonPlatformServices is exported from it. ADR 0032 and AGENTS.md state no changed path.

Transitional testing subpaths

Two ./testing/* entries are added, each deleted with its consumers in the relocation layers:

  • ./testing/server/daemon-runtime: the four teardownDaemonSessionForShutdown tests under src/__tests__/daemon-composition/server.
  • ./testing/daemon-command-registry: test/integration/nightly/concurrency-torture/bindings.ts, which deliberately consumes the production lock decision.

Subpath exports

Package Before After
daemon 107 (7 production + 100 testing) 103 (. + 100 testing + 2 transitional)
command-registry 21 21 (owner-files already existed)
daemon-contracts, host-kit, test-kit, kernel unchanged unchanged

Validation

On the pushed head: pnpm check:quick, pnpm check:layering, pnpm check:fallow, pnpm check:gate-manifest, pnpm check:production-exports, pnpm check:affected --run, pnpm format:check, and after pnpm build: check:bundle-owner-files, check:package, check:doc-prose. The wire-compat ledger is untouched.

Not in this PR: moving the ./testing/* consumers into the package (next layers). The handoff notes name two candidates that may need a decision there: the client abort tests, which run the real client against the real daemon transport, and the nightly concurrency-torture bindings.

🤖 Generated with Claude Code

@thymikee thymikee changed the title refactor/daemon single entry refactor(daemon): add the single package entry and resolve its metadata consumers Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.25 MB 5.25 MB 0 B
Package (unpacked) 5.25 MB 5.25 MB 0 B
Package (download) 1.58 MB 1.58 MB +13 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 28.2 ms 29.2 ms +1.0 ms
CLI --help 80.7 ms 80.0 ms -0.7 ms

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 56 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/command-registry/src/owner-files.ts">

<violation number="1" location="packages/command-registry/src/owner-files.ts:53">
P3: The `generic` route is not lazy: the handler chain statically imports its module. Narrow this statement to specialized routes so the metadata comment does not misdescribe the generic route.</violation>
</file>

<file name="docs/adr/0033-collocation-decision-table.md">

<violation number="1" location="docs/adr/0033-collocation-decision-table.md:198">
P3: `session-lifecycle/index.ts` and `session-observability/index.ts` remain internal re-export barrels; qualify this as the only public package barrel rather than the only allowed barrel.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic


/**
* Development-only owner-file navigation claims for each daemon route. The route's runtime
* binding is its lazy loader in the daemon's handler table; this map is tooling metadata only

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P3: The generic route is not lazy: the handler chain statically imports its module. Narrow this statement to specialized routes so the metadata comment does not misdescribe the generic route.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/command-registry/src/owner-files.ts, line 53:

<comment>The `generic` route is not lazy: the handler chain statically imports its module. Narrow this statement to specialized routes so the metadata comment does not misdescribe the generic route.</comment>

<file context>
@@ -46,3 +47,28 @@ export const COMMAND_OWNER_FILES = buildOwnerFiles(RAW_COMMAND_DESCRIPTORS) sati
+
+/**
+ * Development-only owner-file navigation claims for each daemon route. The route's runtime
+ * binding is its lazy loader in the daemon's handler table; this map is tooling metadata only
+ * `explain:command` reads, so it lives with the command claims above and the bundler drops it.
+ *
</file context>
Suggested change
* binding is its lazy loader in the daemon's handler table; this map is tooling metadata only
* Specialized routes bind through lazy loaders in the daemon's handler table; this map is tooling metadata only

`@agent-device/daemon` has one entry, `.`, which is `packages/daemon/src/index.ts`: explicit named
re-exports of what the daemon process root uses (`startDaemonRuntime` and the types its
composition and platform-runtime modules name), no `export *`. It is the package boundary, the
one place a barrel is allowed; the layer folders hold no barrel. A value import of the package

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P3: session-lifecycle/index.ts and session-observability/index.ts remain internal re-export barrels; qualify this as the only public package barrel rather than the only allowed barrel.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At docs/adr/0033-collocation-decision-table.md, line 198:

<comment>`session-lifecycle/index.ts` and `session-observability/index.ts` remain internal re-export barrels; qualify this as the only public package barrel rather than the only allowed barrel.</comment>

<file context>
@@ -192,20 +192,25 @@ files have no seam (published facade, public-type collision, root dependency fac
+`@agent-device/daemon` has one entry, `.`, which is `packages/daemon/src/index.ts`: explicit named
+re-exports of what the daemon process root uses (`startDaemonRuntime` and the types its
+composition and platform-runtime modules name), no `export *`. It is the package boundary, the
+one place a barrel is allowed; the layer folders hold no barrel. A value import of the package
+evaluates the daemon server graph, so root code that needs only command metadata reads it from
+its owner: the route owner-file claims sit beside the per-command claims in
</file context>
Suggested change
one place a barrel is allowed; the layer folders hold no barrel. A value import of the package
only public package barrel; legacy internal barrels remain in subfolders, not at the layer roots. A value import of the package

Comment thread docs/adr/0033-collocation-decision-table.md
@thymikee

Copy link
Copy Markdown
Member Author

This looks good at 7fd5aa3. Every removed subpath's consumer is resolved, and the route owner-file map now sits beside the DaemonCommandRoute type it is keyed by, with no dependency back on the daemon. I know of no conflicts. I did not run the layering, fallow, eager-closure or affected gates, so I took those results from the PR body.

Smoke Tests is still running and has not failed. It matters here because src/daemon.ts:2 now loads startDaemonRuntime through the new "." export, so it exercises daemon start through the new entry.

Not blocking, take or leave these: the index re-exports DaemonRuntimeController, DaemonRuntimeDepsInput, DaemonRequest and DaemonInvokeFn, which only tests import, so either move them to the ./testing entries or widen the ADR 0033 sentence; and the parity check at command-descriptor-parity.test.ts:172 no longer asserts the daemon's canRunReplayScopedAction, so you could add that assertion to the moved daemon core suite.

The three cubic-dev-ai doc-wording threads still apply and are small: the "lazy loader" wording at owner-files.ts:53 (#3633 (comment)), the session-lifecycle and session-observability barrels against the ADR's no-barrel line (#3633 (comment)), and "one production entry" in the ADR (#3633 (comment)).

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 15, 2026
thymikee and others added 3 commits October 15, 2026 12:39
…onsumers at command-registry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thymikee
thymikee force-pushed the refactor/daemon-single-entry branch from 7fd5aa3 to 95686fd Compare October 15, 2026 10:48
@thymikee
thymikee merged commit a907a91 into main Oct 15, 2026
22 checks passed
@thymikee
thymikee deleted the refactor/daemon-single-entry branch October 15, 2026 10:55
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-15 10:56 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant