improve(signal): make transport ownership account-scoped#108345
improve(signal): make transport ownership account-scoped#108345jesse-merhi wants to merge 1 commit into
Conversation
0b55dc6 to
f8d288b
Compare
|
Codex review: needs maintainer review before merge. Reviewed July 21, 2026, 12:28 AM ET / 04:28 UTC. Summary PR surface: Source +2097, Tests +2567, Docs +17, Config +4, Generated 0, Other +4. Total +4689 across 60 files. Reproducibility: yes. for the current architectural problem: current main visibly resolves flat transport fields and performs runtime auto-detection, while the PR replaces those paths with account-owned concrete transports. A live multi-account Signal deployment is still needed to prove the migration and recovery behavior end to end. Review metrics: 2 noteworthy metrics.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Adopt one canonical account-owned Signal transport contract only after a Signal/config owner confirms the doctor migration and fresh-process update recovery preserve existing deployments and intentionally accept the plugin-doctor execution boundary. Do we have a high-confidence way to reproduce the issue? Yes for the current architectural problem: current main visibly resolves flat transport fields and performs runtime auto-detection, while the PR replaces those paths with account-owned concrete transports. A live multi-account Signal deployment is still needed to prove the migration and recovery behavior end to end. Is this the best way to solve the issue? Unclear: the owner-local transport and doctor design fits the repository’s plugin-boundary policy, but maintainers must decide whether automatic fresh-process plugin doctor execution is the acceptable update-recovery mechanism. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against be009ee5570f. Label changesLabel justifications:
Evidence reviewedPR surface: Source +2097, Tests +2567, Docs +17, Config +4, Generated 0, Other +4. Total +4689 across 60 files. View PR surface stats
Security concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (4 earlier review cycles)
|
f8d288b to
4a4cf19
Compare
5e45a67 to
6a46dae
Compare
What Problem This Solves
Signal transport ownership was split across flat channel fields, per-account state, setup policy, and runtime auto-detection. That made multi-account managed-native setup vulnerable to port collisions and let external-native or container accounts fall into local-daemon assumptions.
This change gives every effective Signal account one concrete transport owned by that account. Runtime no longer detects or changes transport kind. Signal setup owns detection, probing, canonical writes, and managed-native port allocation.
Canonical Contract
The root
channels.signal.transportbelongs only to the effective default account. Named accounts ownchannels.signal.accounts.<id>.transportand do not inherit the root transport.Public Signal setup seams are exported from
extensions/signal/api.tsand implemented inextensions/signal/src/setup-transport.ts:detectSignalTransport: setup-only native/container detection.probeSignalTransport: probe one explicit transport.prepareSignalManagedNativeTransport: preserve the selected account's managed options while allocating a collision-free port across effective sibling endpoints.writeSignalAccountTransport: validate and write a canonical account-owned transport.Callers creating managed-native accounts prepare first, then write. Port allocation, host/URL validation, endpoint alignment, and collision policy stay inside Signal.
Migration And Recovery
openclaw doctor --fixmigrates shipped flat Signal fields to the canonical transport union while preserving account identity, default-account ownership, configured paths/options, disabled accounts, and container account requirements.Ambiguous offline auto-mode endpoints remain pending rather than being guessed. The exception is an explicitly gateway-owned legacy daemon (
autoStart: true), which migrates to managed-native even while the update has that daemon stopped.When an external plugin package or channel changes, update finalization reruns the updated plugin's doctor and strict config validation in the updated process before restart. Doctor, entrypoint, and validation failures are structured and fail closed; a previously stopped service is restored only when the updated schema accepts the resulting config.
Why Non-Signal Files Still Change
The earlier generic channel/plugin hooks have been removed. The remaining non-
extensions/signal/**changes are bounded to existing owner seams:src/config/**;There are no changes to generic channel add/CLI discovery, generic doctor flow, read-only plugin loading, official-plugin recovery capabilities, or
src/cli/update-cli/update-command.ts.Config surface counts change from core/channel/plugin
2851/3680/3537to2832/3693/3537: 13 canonical channel nodes are added, while 19 core nodes disappear with the retired flat Signal surface/schema extraction. Plugin config count is unchanged.Evidence
mainas one commit:6a46dae24297cfba23acd0acedd9baad31d3afe1.git diff --checkpassed.The local shell currently uses Node 25.2.1, whose embedded SQLite version is intentionally rejected by the repository's WAL-safety guard. The three affected update-sentinel tests pass on the supported remote runtime as part of the 243-test updater suite above.