Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions docs/adr/0019-request-bound-platform-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -833,12 +833,15 @@ therefore structurally enforced rather than periodically measured.
Some request-path work asks the host machine something without ever taking a device runtime:
concrete local readiness, boot-time and runner-session observation, and open-target
classification. Those asks now cross the daemon boundary as one required dependency,
`DaemonPlatformServices` (`src/daemon/platform-services.ts`), composed by the root in
`src/platform-runtime-daemon-services.ts` and threaded root → `RequestRouterDeps` → the request
execution scope → the handlers and consumers. Stale-claim reconciliation gets the same treatment
for the one act it may not perform itself: the root supplies a `ClaimRecoveryGatewayFactory`
(`src/daemon/device/claim-recovery-gateway.ts`), and the daemon keeps the transaction — what to
rebuild from (the dead owner's recorded state dir), in what order, and when to dispose it.
`DaemonPlatformServices` (`src/daemon/platform-services.ts`), assembled by the daemon runtime's
root-composition module in `src/daemon-composition.ts` — which reaches the concrete adapters
through `src/platform-runtime-daemon-services.ts` behind a function-scoped `await import` — and
threaded composition → `startDaemonRuntime` deps → `RequestRouterDeps` → the request execution
scope → the handlers and consumers. Stale-claim reconciliation gets the same treatment
for the one act it may not perform itself: the composition supplies the `ClaimRecoveryGatewayFactory`
the daemon declares in `src/daemon/device/claim-recovery-gateway.ts`, built from
`src/platform-runtime-claim-recovery.ts` (likewise deferred), and the daemon keeps the transaction —
what to rebuild from (the dead owner's recorded state dir), in what order, and when to dispose it.

The port is not a raw escape hatch back into platform mechanics. Its observation members are the
already-published neutral contract types from `@agent-device/contracts`, readiness is a boolean,
Expand Down
8 changes: 8 additions & 0 deletions docs/adr/0022-daemon-platform-runtime-coupling.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ Accepted (2026-09-06). Implements the audit deliverables of issue #2278. The cla
inventory and the structural no-regrowth checks are gate-enforced; this ADR records the decisions
and points at the gates rather than restating the inventory.

Amended 2026-10-11 by the PR-6 composition extraction: the daemon-runtime composition edges this
ADR classified (the gateway/diagnostics/resource-cleanup/lifecycle edges, the provider-runtime
hubs, and the platform-services and claim-recovery dynamic edges) moved out of `src/daemon/` into
the process-root composition module `src/daemon-composition.ts`, which R76 does not see because it
is no longer a daemon-zone importer. The R76 inventory now carries only the leaked
selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the

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: Section 2 follows this amendment, so “above” points readers in the wrong direction. Change it to “below.”

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/0022-daemon-platform-runtime-coupling.md, line 14:

<comment>Section 2 follows this amendment, so “above” points readers in the wrong direction. Change it to “below.”</comment>

<file context>
@@ -6,6 +6,14 @@ Accepted (2026-09-06). Implements the audit deliverables of issue #2278. The cla
+hubs, and the platform-services and claim-recovery dynamic edges) moved out of `src/daemon/` into
+the process-root composition module `src/daemon-composition.ts`, which R76 does not see because it
+is no longer a daemon-zone importer. The R76 inventory now carries only the leaked
+selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the
+record of how each was classified.
+
</file context>
Suggested change
selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the
selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes below remain the

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: This R76 importer path omits the src/ prefix, so the amended ADR points readers to a nonexistent path. Use the repository-relative path src/daemon/direct-ios-selector.ts.

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/0022-daemon-platform-runtime-coupling.md, line 14:

<comment>This R76 importer path omits the `src/` prefix, so the amended ADR points readers to a nonexistent path. Use the repository-relative path `src/daemon/direct-ios-selector.ts`.</comment>

<file context>
@@ -6,6 +6,14 @@ Accepted (2026-09-06). Implements the audit deliverables of issue #2278. The cla
+hubs, and the platform-services and claim-recovery dynamic edges) moved out of `src/daemon/` into
+the process-root composition module `src/daemon-composition.ts`, which R76 does not see because it
+is no longer a daemon-zone importer. The R76 inventory now carries only the leaked
+selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the
+record of how each was classified.
+
</file context>
Suggested change
selector-query edge (`daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the
+selector-query edge (`src/daemon/direct-ios-selector.ts`); the section-2 outcomes above remain the

record of how each was classified.

## 1. Context

The platform-package migration removed direct production dependencies from `src/daemon/**` to
Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0033-collocation-decision-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ optimal.
| `src/platform-runtime-daemon-lifecycle.ts` | retain for this batch | Same path-keyed R13/ADR 0022 seam: relocation is possible only with coordinated changes to those declarations. |
| `src/platform-runtime-device-boot.ts` | retain for this batch | Same path-keyed R13/ADR 0022 seam. |
| `src/platform-runtime-resource-cleanup.ts` | retain for this batch | Same path-keyed R13/ADR 0022 seam. |
| `src/provider-credential-fingerprint.ts` | keep | Daemon ⇄ client shared contract from the same #2559 decision as `daemon-policy-file.ts`; #3288 declares its zone beside the provider composition that reads the credentials it fingerprints. |
| `src/provider-credential-fingerprint.ts` | keep (type extracted) | Daemon ⇄ client shared contract from the same #2559 decision as `daemon-policy-file.ts`; #3288 declares its zone beside the provider composition that reads the credentials it fingerprints. PR 6 of the daemon extraction moved only the `DaemonProviderCredentials` declaration to `packages/daemon-contracts` (`./provider-credentials`), the same shared-below-both landing as the policy file; the fingerprinting implementation stays here because it reads the installed-plugin manifest. |
| `src/provider-limrun-runtime.ts` | keep | Proposed → provider-limrun, but there is no seam: the class's constructor self-builds the root dependency factory (`src/sdk/limrun-runtime-dependencies.ts`), which is the ADR 0019 composition seam — it loads the root's adb-host binder, core Android interactor, and platform-runtime app-state helpers that the package must not import. Moving the class means moving that composition, which is design, not a move. |
| `src/request-progress-protocol.ts` | moved → `packages/daemon-contracts/src/request-progress-protocol.ts` | Daemon ⇄ client shared contract from the same #2559 decision — the client reads it statically (`daemon-client-progress.ts`) and the server through `src/daemon/server/`, so only #2559's shared-placement boundary and the wire-compat ledgers pin it; declared `daemon-contracts` by #3288 and now physically placed by the extraction. Contracts was considered and R18 keeps contracts free of envelope validation mechanics. The wire-ledger keys moved with the file. |
| `src/runtime-command-surface.ts` | moved → `src/command-runtime/runtime-command-surface.ts` ([#3299](https://github.com/callstack/agent-device/pull/3299)) | Physical move landed with `runtime-factory.ts` as one assembly group: the command-surface binding sits beside the factory it composes, under the folder that derives its `command-runtime` zone, so `topFolder` replaces the per-file `ROOT_MODULE_ZONES` row. |
Expand Down
4 changes: 4 additions & 0 deletions packages/daemon-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
"types": "./src/daemon-shutdown-report.ts",
"default": "./src/daemon-shutdown-report.ts"
},
"./provider-credentials": {
"types": "./src/provider-credentials.ts",
"default": "./src/provider-credentials.ts"
},
"./request-progress-protocol": {
"types": "./src/request-progress-protocol.ts",
"default": "./src/request-progress-protocol.ts"
Expand Down
15 changes: 15 additions & 0 deletions packages/daemon-contracts/src/provider-credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* The provider credentials a daemon started with, and the state dir that names that daemon.
*
* A `lease_allocate` request carries the caller's own fingerprint so a lease can be fenced to one
* credential set (#2559): the daemon compares the request's value against the fingerprint it
* computed from its own startup environment, and both sides read this one declaration — the
* daemon's implementation stays in the process root (`src/provider-credential-fingerprint.ts`),
* which the daemon client imports; the vocabulary lives here because that fingerprint module must
* not carry a type edge into `src/daemon` (#2559).
*/
export type DaemonProviderCredentials = Readonly<{
/** Undefined when the daemon's environment holds none of the credentials such a lease reads. */
fingerprint(provider: string, leaseBackend?: string): string | undefined;
stateDir: string;
}>;
Loading
Loading