LearnNewsExamplesServices
Frontmatter
id13920
titleDeployment runtime access primitive for self-healing
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-gpt, neo-opus-grace
createdAtJun 23, 2026, 12:26 PM
updatedAtJun 23, 2026, 3:18 PM
githubUrlhttps://github.com/neomjs/neo/issues/13920
authorneo-gpt
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 23, 2026, 3:18 PM

Deployment runtime access primitive for self-healing

Closed v13.1.0/archive-v13-1-0-chunk-6 enhancementaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 23, 2026, 12:26 PM

Context

Parent: #13860

Related: #13874, #13884, #13914, #13916

Authored by @neo-gpt as ticket substrate from the converged #13860 ledger. This preserves @neo-opus-grace's ownership statement on #13860 ("Next (mine): I file the L0 primitive sub") while making the L0 dependency concrete and claimable.

Release classification: boardless - P0 deployment-immune-system blocker, but not automatically v13-boarded unless the operator promotes it.

Live latest-open sweep: checked the latest 20 open issues at 2026-06-23T10:24:34Z; no equivalent L0 primitive sub found. Scope-specific live sweep for deployment-runtime access, L0 primitive, socket holder, two capability envelopes, and read-observe lifecycle-write returned #13860, #13914, #13874, and unrelated older blocked/epic issues, but no dedicated L0 sub. A2A in-flight sweep caveat: the current Codex harness exposes no list_messages tool; current wake thread and live GitHub state were checked instead.

The Problem

The self-healing stack is now blocked by a missing L0 deployment-runtime access primitive.

#13860 converged that the diagnostics/recovery system was built top-down: #13874/#13884 can act only if there is a safe runtime-access holder, and #13914 can prove deployment state only if it can read raw logs/stats/inspect output. #13915 proved the failure mode: the B1 actuator can be internally clean and CI-green while still not being merge-proof because it chose a compose-CLI executor without the shared L0 decision, socket mount, container tooling, or read/write envelope split.

The current cloud/local incidents are the falsifiers: status/probe-only confidence did not reveal the real degraded state, and manual runtime inspection was needed. The system needs one deny-by-default primitive before L1 detect, L2 diagnose, B1 actuator rebase, or #13914 observability can be completed coherently.

The Architectural Reality

#13860 now has two-family convergence:

  • @neo-opus-grace resequenced the immune system dependency-up and identified L0 as the keystone.
  • @neo-gpt added the accepted two-envelope refinement: one orchestrator-resident holder, with a read-observe envelope for logs/stats/inspect and a lifecycle-write envelope for restart/redeploy.
  • @neo-opus-grace accepted the graph-direct correction: recovery-run and diagnosis events publish to the Memory Core graph SSOT directly, not through #13889's A2A-message WAL.

ADR-0026 still leaves OQ-1 open: socket API vs compose CLI vs sidecar. That decision must be resolved here, not implicitly in B1 or #13914. ADR-0026 §2.3 currently scopes the privileged path too narrowly as actuator-only; the converged L0 shape is one holder with two separately allowlisted capability envelopes.

Pre-Flight (structural fast-path): future ai/daemons/orchestrator/services/DeploymentRuntimeAccessService.mjs matches sibling service pattern of RecoveryActuatorService.mjs / ProcessSupervisorService.mjs in ai/daemons/orchestrator/services/; sibling-file-lift applies, no novel directory choice, and no ArchitectureOverview map update is required for another orchestrator service.

The Fix

Define and implement the L0 deployment-runtime access primitive:

  • Resolve ADR-0026 OQ-1 with an explicit MVP mechanism decision: docker socket API wrapper, compose-CLI wrapper, or sidecar, with falsifiers documented.
  • Add one orchestrator-owned runtime-access service with service-identity resolution and deny-by-default allowlists.
  • Expose two capability envelopes over the same holder:
    • read-observe: allowlisted logs/stats/inspect operations for #13914;
    • lifecycle-write: allowlisted restart/redeploy operations for #13884 / B1.
  • Keep separate operation allowlists, audit labels, and tests for read vs write so observability cannot accidentally gain lifecycle authority.
  • Add AiConfig template leaves/env overrides for enablement, runtime mechanism, allowed services/operations, socket/sidecar/CLI path, command timeouts, and audit mode.
  • Add deployment wiring or an explicit operator-residual row for the real cloud/local runtime handle: socket mount/tooling/sidecar reachability, not just unit mocks.
  • Update ADR-0026 or add a successor note so #13915, #13914, L1 detect, and L2 diagnose have a source of authority to consume.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
L0 runtime-access mechanism #13860 convergence + ADR-0026 OQ-1 Choose one MVP mechanism and document why socket API / compose CLI / sidecar alternatives are accepted or rejected If mechanism cannot prove service identity + allowlisting, choose the sidecar fallback or keep B1/#13914 blocked ADR-0026 update / PR body L1 ADR diff + L2 mechanism tests
DeploymentRuntimeAccessService #13860 L0 and sibling orchestrator services One orchestrator-owned holder resolves service identity and mediates all runtime read/write operations Disabled by default; fail loud when unconfigured JSDoc + AiConfig comments L2 unit tests
Read-observe envelope #13914 + #13860 two-envelope convergence Allowlisted logs/stats/inspect only; no lifecycle operations reachable through read API Deny unknown services/operations before executor access JSDoc + PR body L2 allowlist/denial tests
Lifecycle-write envelope #13884 / ADR-0026 B1 Allowlisted restart/redeploy operations only; separate write allowlist and audit labels Deny unknown service/action before executor access JSDoc + PR body L2 allowlist/denial tests + B1 rebase path
Config and deployment wiring AiConfig SSOT + cloud/local parity requirement Template leaves/env overrides describe the runtime handle and host mode without hidden defaults Operator residual allowed only for real cloud smoke, not for unit/config coverage ai/config.template.mjs comments / deployment docs if touched L2 config tests + L3 smoke or explicit residual
Audit/proof surface #13916 graph SSOT + #13914 remote proof Runtime-access actions/observations emit structured audit metadata that #13916/#13914 can expose If graph publish is unavailable, fail loud or report residual; do not silently drop proof JSDoc / PR body L2 audit metadata test

Decision Record impact

Amends ADR-0026 by resolving or narrowing OQ-1 and widening the privileged primitive from actuator-only to a shared two-envelope deployment-runtime-access holder. Depends on ADR-0025/ADR-0026 safety constraints: detect != actuator, lifecycle/config-only, persisted anti-thrash at the consumer layer, and no arbitrary code execution.

Decision Record: Required - ADR-0026 update in the implementation PR.

Acceptance Criteria

  • ADR-0026 OQ-1 is resolved or narrowed with an explicit mechanism decision and fallback rationale.
  • A single orchestrator-owned runtime-access holder mediates both read-observe and lifecycle-write operations.
  • Read and write envelopes have separate allowlists, separate APIs, separate audit labels, and tests proving cross-envelope operations are denied.
  • Service identity resolution is allowlist-backed and cannot execute against arbitrary container/service names.
  • AiConfig template leaves/env overrides cover enablement, mechanism choice, allowed services/operations, runtime handle path, timeout, and audit behavior.
  • Deployment wiring is present for the chosen mechanism, or the PR declares a concrete operator-owned L3 residual for real cloud/local smoke.
  • #13914 can consume the read-observe envelope without importing the write actuator.
  • #13884/#13915 can rebase onto the lifecycle-write envelope without owning its own docker/compose executor.
  • Runtime-access actions/observations expose structured proof metadata suitable for #13916/#13914.

Out of Scope

  • Implementing #13914's MCP tool surface.
  • Implementing L1 container-health detect or L2 diagnosis emission.
  • Rebasing/merging #13915's B1 actuator.
  • A2A-message WAL durability (#13889) or message graph replay (#13892).
  • Arbitrary container exec, shell access, or non-lifecycle runtime mutation.

Avoided Traps

  • Do not weld docker access into RecoveryActuatorService; L0 is shared substrate, not a B1-private helper.
  • Do not let read-only observability inherit write authority through a convenient shared command runner.
  • Do not choose compose CLI solely because it is easy to mock; the mechanism must be deployable from the orchestrator container.
  • Do not make status/probe-only proof the acceptance evidence; the incident falsified that.
  • Do not route typed immune-system graph proof through #13889's A2A-message WAL unless the payload is actually an A2A message.

Related

Parent: #13860

Related: #13874, #13884, #13914, #13915, #13916, #13889

Origin Session ID: 019ef378-527d-7393-bc74-ec3a1d3f2ddf

Handoff Retrieval Hints: #13860 L0 deployment runtime access primitive two envelopes read-observe lifecycle-write; ADR-0026 OQ-1 socket API compose CLI sidecar; #13915 B1 actuator L0 hold #13914 inspect_deployment read envelope

tobiu referenced in commit def8abc - "feat(ai): add deployment runtime access holder (#13920) (#13925)" on Jun 23, 2026, 3:18 PM
tobiu closed this issue on Jun 23, 2026, 3:18 PM