Context
The deployment immune-system path now has ADR-0025 for detect/diagnose and ADR-0026 for the recovery actuator, plus runtime-access and deployment-state bridge work. During the deployment-readiness audit on 2026-06-24, the current Neo default was verified as AiConfig.orchestrator.recoveryActuator.enabled = leaf(false, "NEO_RECOVERY_ACTUATOR_ENABLED", "boolean") in ai/config.template.mjs. That means a deployment can ship the diagnostics/recovery substrate and still refuse every recovery action unless an operator discovered and set the opt-in env var.
The Problem
For the recovery half of the immune system, disabled-by-default is the wrong failure mode. A burning deployment should not silently deny bounded recovery because the deployment missed a new opt-in. Operators who do not want recovery can disable it explicitly; the default should let the actuator participate once its target allowlists and runtime-access envelopes are configured.
Architectural Reality
- ADR-0025 owns detection and diagnosis.
- ADR-0026 owns the act half: bounded, reversible, rate-limited recovery or escalation.
RecoveryActuatorService.apply() already fails closed on unsupported actions, disabled config, missing allowlist entries, target kind/action mismatch, and anti-thrash gates.
- ADR-0019 applies: this must be a real AiConfig leaf default, not a use-site fallback, type coercion, or alias.
The Fix
Change the Neo-side recovery actuator default so NEO_RECOVERY_ACTUATOR_ENABLED is opt-out by default. Keep the existing allowlist and action-envelope gates intact. Update fixtures/tests that assert Tier-1 defaults so the default contract is explicit.
Contract Ledger Matrix
| Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
AiConfig.orchestrator.recoveryActuator.enabled |
ADR-0019 + ADR-0026 |
Default resolves enabled unless NEO_RECOVERY_ACTUATOR_ENABLED=false is set |
Existing allowlists and anti-thrash still deny unsafe targets/actions |
config template comments and tests |
unit default fixture + recovery actuator disabled-override coverage |
RecoveryActuatorService.apply() |
ADR-0026 |
No hidden default; read the resolved leaf and act only when leaf is true |
enabled=false remains an explicit operator opt-out |
JSDoc remains controller-blind |
existing service tests plus new/default-adjusted assertions |
Decision Record impact
aligned-with ADR-0019, ADR-0025, and ADR-0026. This does not loosen target allowlists or runtime-access privilege; it corrects the activation default for the approved recovery actuator.
Acceptance Criteria
Out of Scope
- Adding a new diagnosis controller.
- Broadening Docker/runtime-access privileges.
- Adding public orchestrator routes or exposing the orchestrator as a public MCP surface.
- Changing target allowlist defaults beyond the actuator enabled flag.
Related
Parent recovery epic: #13874. Diagnostics sibling: #13860. Deployment proof: #13936. Runtime access holder: #13920. ADRs: ADR-0019, ADR-0025, ADR-0026.
Creation evidence
Live latest-open sweep: checked latest 20 open issues at 2026-06-24T13:26:55Z; no equivalent narrow ticket found. A2A in-flight sweep: checked latest 30 messages; no competing claim found. KB ticket sweep: no existing issue for NEO_RECOVERY_ACTUATOR_ENABLED default true found.
Handoff Retrieval Hints: recovery actuator enabled by default NEO_RECOVERY_ACTUATOR_ENABLED ADR-0026, actuator-disabled AiConfig leaf default recovery daemon
Context
The deployment immune-system path now has ADR-0025 for detect/diagnose and ADR-0026 for the recovery actuator, plus runtime-access and deployment-state bridge work. During the deployment-readiness audit on 2026-06-24, the current Neo default was verified as
AiConfig.orchestrator.recoveryActuator.enabled = leaf(false, "NEO_RECOVERY_ACTUATOR_ENABLED", "boolean")inai/config.template.mjs. That means a deployment can ship the diagnostics/recovery substrate and still refuse every recovery action unless an operator discovered and set the opt-in env var.The Problem
For the recovery half of the immune system, disabled-by-default is the wrong failure mode. A burning deployment should not silently deny bounded recovery because the deployment missed a new opt-in. Operators who do not want recovery can disable it explicitly; the default should let the actuator participate once its target allowlists and runtime-access envelopes are configured.
Architectural Reality
RecoveryActuatorService.apply()already fails closed on unsupported actions, disabled config, missing allowlist entries, target kind/action mismatch, and anti-thrash gates.The Fix
Change the Neo-side recovery actuator default so
NEO_RECOVERY_ACTUATOR_ENABLEDis opt-out by default. Keep the existing allowlist and action-envelope gates intact. Update fixtures/tests that assert Tier-1 defaults so the default contract is explicit.Contract Ledger Matrix
AiConfig.orchestrator.recoveryActuator.enabledNEO_RECOVERY_ACTUATOR_ENABLED=falseis setRecoveryActuatorService.apply()enabled=falseremains an explicit operator opt-outDecision Record impact
aligned-with ADR-0019, ADR-0025, and ADR-0026. This does not loosen target allowlists or runtime-access privilege; it corrects the activation default for the approved recovery actuator.
Acceptance Criteria
ai/config.template.mjsdefaults the recovery actuator to enabled via the existingleaf()contract.actuator-disabled.Out of Scope
Related
Parent recovery epic: #13874. Diagnostics sibling: #13860. Deployment proof: #13936. Runtime access holder: #13920. ADRs: ADR-0019, ADR-0025, ADR-0026.
Creation evidence
Live latest-open sweep: checked latest 20 open issues at 2026-06-24T13:26:55Z; no equivalent narrow ticket found. A2A in-flight sweep: checked latest 30 messages; no competing claim found. KB ticket sweep: no existing issue for
NEO_RECOVERY_ACTUATOR_ENABLEDdefault true found.Handoff Retrieval Hints:
recovery actuator enabled by default NEO_RECOVERY_ACTUATOR_ENABLED ADR-0026,actuator-disabled AiConfig leaf default recovery daemon