Frontmatter
| title | feat(ai): add deployment-state bridge snapshot (#13926) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 23, 2026, 6:32 PM |
| updatedAt | Jun 23, 2026, 9:18 PM |
| closedAt | Jun 23, 2026, 9:17 PM |
| mergedAt | Jun 23, 2026, 9:17 PM |
| branches | dev ← codex/13926-deployment-state-bridge |
| url | https://github.com/neomjs/neo/pull/13935 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |
Merged

neo-gpt
commented on Jun 23, 2026, 6:54 PM
Author update after operator review:
- Read
src/core/Base.mjs,src/Neo.mjs, and ADR 0019 again. - Removed the new
bridgeConfig_/bridgeConfigpass-through; the bridge now reads Tier-1AiConfig.orchestrator.deploymentStateBridge.*leaves at the use site. - Removed defensive
AiConfig.orchestrator?.deploymentStateBridge || {}reads from the KB/MC tool services; missing config now fails loud per ADR 0019. - Fixed initial reactive-service setup: the bridge now receives
containerHealthDiagnosisServiceeven whenafterSetContainerHealthDiagnosisServicefires witholdValue === undefinedduring construction/startup. - Added a regression test for that Base/Neo initial reactive propagation path.
Validation after rebasing on current origin/dev:
npm run test-unit -- test/playwright/unit/ai/services/memory-core/helpers/deploymentStateBridgeStore.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 42 passed.npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs test/playwright/unit/ai/daemons/orchestrator/Orchestrator.invariants.spec.mjs-> 78 passed.npm run agent-preflight -- ai/daemons/orchestrator/Orchestrator.mjs ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs ai/mcp/server/knowledge-base/toolService.mjs ai/mcp/server/memory-core/toolService.mjs test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs-> passed.

neo-gpt
commented on Jun 23, 2026, 7:52 PM
Author update after the Base/Neo + ADR 0019 correction:
- Pushed
b768ca26cb535a226422e755231a8cfbf510b4ad. - Removed
DeploymentStateBridgeService.bridgeConfig_and thecfgaccessor; the service now readsAiConfig.orchestrator.deploymentStateBridgeat the actual use sites. - Removed the deployment-state
AiConfig.setEnvOverride()test path; the MCP dispatch test writes/restores the configured snapshot file and calls KB/MC tools without caller-selected paths or singleton mutation. - Kept the initial reactive wiring fix:
beforeSetDeploymentStateBridgeService()intentionally readsthis.containerHealthDiagnosisService, relying on theBase/Neo.createConfig()pending-config getter path to instantiate the service during startup.
Fresh validation:
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 31 passed.npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs test/playwright/unit/ai/daemons/orchestrator/Orchestrator.invariants.spec.mjs-> 78 passed.npm run ai:lint-config-template-ssot-> passed.npm run agent-preflight -- ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> passed.git diff --check-> passed.
CI is running on the pushed head.

neo-gpt
commented on Jun 23, 2026, 8:47 PM

tobiu
APPROVED reviewed on Jun 23, 2026, 9:17 PM
No review body provided.
Resolves #13926
Related: #13860, #13914, #13920, #13924
Adds a graph-independent deployment-state bridge: the internal orchestrator can write a bounded, allowlisted snapshot through the existing deployment runtime holder, while public KB and MC MCP surfaces only get read-only snapshot tools. The public tools do not receive Docker socket, shell, exec, restart, daemon-route, write-actuator authority, or caller-selected file paths; they read only the Tier-1
AiConfig.orchestrator.deploymentStateBridge.snapshotPathleaf.Evidence: L2 (unit coverage plus real KB/MC toolService dispatch against a wedged-model/unhealthy-memory snapshot fixture) -> L3 required (post-merge deployment smoke against the private overlay and shared snapshot mount). Residual: live deployment smoke [#13926].
Deltas from ticket
DeploymentStateBridgeServiceno longer has abridgeConfig_/bridgeConfigpass-through, and deployment-state tests no longer mutate the sharedAiConfigsingleton.containerHealthDiagnosisServiceduring startup via the generated getter/setter path, with regression coverage inOrchestrator.spec.mjs.Test Evidence
node --check ai/services/memory-core/helpers/deploymentStateBridgeStore.mjsnode --check ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjsnode --check ai/daemons/orchestrator/Orchestrator.mjsnode --check ai/mcp/server/knowledge-base/toolService.mjsnode --check ai/mcp/server/memory-core/toolService.mjsnode --check test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjsnpm run test-unit -- test/playwright/unit/ai/services/memory-core/helpers/deploymentStateBridgeStore.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs-> 5 passednpm run test-unit -- test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 29 passednpm run test-unit -- test/playwright/unit/ai/services/memory-core/helpers/deploymentStateBridgeStore.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 42 passednpm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs test/playwright/unit/ai/daemons/orchestrator/Orchestrator.invariants.spec.mjs-> 77 passednpm run ai:lint-config-template-ssotnpm run agent-preflight -- ai/config.template.mjs ai/daemons/orchestrator/Orchestrator.mjs ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs ai/mcp/server/knowledge-base/openapi.yaml ai/mcp/server/knowledge-base/toolService.mjs ai/mcp/server/memory-core/openapi.yaml ai/mcp/server/memory-core/toolService.mjs ai/services/memory-core/helpers/deploymentStateBridgeStore.mjs test/playwright/fixtures/aiConfigDefaults.mjs test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/services/memory-core/helpers/deploymentStateBridgeStore.spec.mjsnpm run agent-preflight -- ai/mcp/server/knowledge-base/toolService.mjs ai/mcp/server/memory-core/toolService.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjsnpm run agent-preflight -- ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs ai/mcp/server/knowledge-base/openapi.yaml ai/mcp/server/knowledge-base/toolService.mjs ai/mcp/server/memory-core/openapi.yaml ai/mcp/server/memory-core/toolService.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjsnpm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 31 passednpm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs test/playwright/unit/ai/daemons/orchestrator/Orchestrator.invariants.spec.mjs-> 78 passednpm run agent-preflight -- ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjsgit diff --checkPost-Merge Validation
NEO_DEPLOYMENT_STATE_BRIDGE_ENABLED, gives orchestrator a writer path, and mounts the sameNEO_DEPLOYMENT_STATE_BRIDGE_SNAPSHOT_PATHread-only into KB and MC.NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICESto the intended deployment service keys.get_deployment_state_snapshotwhile the model runner is wedged and Memory Core is unhealthy or graph-unavailable, proving KB remains a current-state path when healthy.Commits
113be5c900-feat(ai): add deployment-state bridge snapshot (#13926)0ba1ecf999-test(ai): cover deployment-state MCP read path (#13926)16a0bd2ff1-fix(ai): align deployment bridge with reactive config (#13926)6ae9203474-fix(ai): align deployment-state bridge config shape (#13926)b768ca26cb-fix(ai): remove deployment bridge config seam (#13926)Authored by Euclid (GPT-5, Codex Desktop). Session f5e75eee-e7a1-4bf2-b8bf-4ab58d9ec932.
Author update — reactive config cleanup
Fixed the
Baseconfig-shape issue on the #13935 head.DeploymentStateBridgeServicenow keeps inert injected dependencies as plain configs:runtimeAccessServicediagnosisServicenowFnwriteLogThese do not need generated reactive accessors or hook dispatch. The orchestrator-owned
deploymentStateBridgeService_remains reactive becauseOrchestratorhasbeforeSet*/afterSet*wiring for that service.Commit:
004a20df14—fix(ai): keep deployment bridge injections non-reactive (#13926)Validation run locally:
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/services/DeploymentStateBridgeService.spec.mjs→ 2 passednpm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs→ 55 passedgit diff --check→ passedReview request remains assigned to @neo-opus-grace.