@openlife/cli 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (394) hide show
  1. package/INSTALL.md +266 -0
  2. package/LICENSE +21 -0
  3. package/README.md +142 -0
  4. package/bin/openlife.js +3 -0
  5. package/dist/admin_panel_server.js +66 -0
  6. package/dist/cli/AgentManager.js +109 -0
  7. package/dist/cli/AutonomousInstaller.js +134 -0
  8. package/dist/cli/DreamOrganizer.js +88 -0
  9. package/dist/cli/HostInstaller.js +426 -0
  10. package/dist/cli/InstallBanner.js +16 -0
  11. package/dist/cli/InstallFlow.js +256 -0
  12. package/dist/cli/InstallHeadless.js +47 -0
  13. package/dist/cli/InstallModules.js +148 -0
  14. package/dist/cli/InstallStateStore.js +75 -0
  15. package/dist/cli/InstallWizard.js +364 -0
  16. package/dist/cli/ProfileManager.js +163 -0
  17. package/dist/cli/SystemInstaller.js +89 -0
  18. package/dist/cli/WorldClassCommands.js +208 -0
  19. package/dist/design/DesignMdImporter.js +82 -0
  20. package/dist/design/DesignMdMode.js +93 -0
  21. package/dist/design/DesignMdRegistry.js +67 -0
  22. package/dist/index.js +2575 -0
  23. package/dist/memory/ConversationMemory.js +33 -0
  24. package/dist/memory/LocalMemoryProvider.js +86 -0
  25. package/dist/memory/Mem0Provider.js +16 -0
  26. package/dist/memory/MemoryNamespacePolicy.js +27 -0
  27. package/dist/memory/MemoryOrchestrator.js +65 -0
  28. package/dist/memory/MemoryPromotionFlow.js +32 -0
  29. package/dist/memory/MemoryProvider.js +2 -0
  30. package/dist/memory/MemoryProviderRegistry.js +27 -0
  31. package/dist/memory/MemoryRetentionPolicy.js +60 -0
  32. package/dist/memory/MempalaceProvider.js +72 -0
  33. package/dist/memory/OmniMemory.js +106 -0
  34. package/dist/memory/RedisAgentMemoryProvider.js +16 -0
  35. package/dist/memory/SessionManager.js +86 -0
  36. package/dist/memory/ZepGraphitiProvider.js +16 -0
  37. package/dist/orchestrator/AgentRegistry.js +56 -0
  38. package/dist/orchestrator/AgentScoring.js +82 -0
  39. package/dist/orchestrator/AgentTeam.js +22 -0
  40. package/dist/orchestrator/ArbitrationAgent.js +43 -0
  41. package/dist/orchestrator/ArbitrationScorecard.js +17 -0
  42. package/dist/orchestrator/AssetPromotionEngine.js +65 -0
  43. package/dist/orchestrator/AssetReuseRouter.js +63 -0
  44. package/dist/orchestrator/BenchmarkEngine.js +75 -0
  45. package/dist/orchestrator/Brain.js +298 -0
  46. package/dist/orchestrator/CadenceEngine.js +76 -0
  47. package/dist/orchestrator/CapabilityRouter.js +36 -0
  48. package/dist/orchestrator/CommandLanguage.js +27 -0
  49. package/dist/orchestrator/CommandRouter.js +70 -0
  50. package/dist/orchestrator/ConsequenceForecaster.js +286 -0
  51. package/dist/orchestrator/CronManager.js +286 -0
  52. package/dist/orchestrator/DynamicAgentBuilder.js +48 -0
  53. package/dist/orchestrator/DynamicAgentExecutor.js +15 -0
  54. package/dist/orchestrator/EnterpriseAgenticCore.js +276 -0
  55. package/dist/orchestrator/ExecutionBoard.js +86 -0
  56. package/dist/orchestrator/ExecutionIntent.js +13 -0
  57. package/dist/orchestrator/ExecutionModePolicy.js +48 -0
  58. package/dist/orchestrator/ExecutionRouter.js +9 -0
  59. package/dist/orchestrator/ExecutionState.js +20 -0
  60. package/dist/orchestrator/ExecutorHealth.js +86 -0
  61. package/dist/orchestrator/ExternalCatalogRegistry.js +83 -0
  62. package/dist/orchestrator/Gatekeeper.js +414 -0
  63. package/dist/orchestrator/Gateway.js +508 -0
  64. package/dist/orchestrator/GovernanceConsentStore.js +66 -0
  65. package/dist/orchestrator/GovernanceLayer.js +179 -0
  66. package/dist/orchestrator/GovernancePolicyStore.js +53 -0
  67. package/dist/orchestrator/GovernanceScopeLedger.js +134 -0
  68. package/dist/orchestrator/GovernanceScopePolicy.js +67 -0
  69. package/dist/orchestrator/IntentClassifier.js +45 -0
  70. package/dist/orchestrator/JobLifecycle.js +91 -0
  71. package/dist/orchestrator/LearningRouter.js +24 -0
  72. package/dist/orchestrator/MediaManager.js +92 -0
  73. package/dist/orchestrator/MemoryCuratorAgent.js +41 -0
  74. package/dist/orchestrator/MissionState.js +155 -0
  75. package/dist/orchestrator/ModelManager.js +84 -0
  76. package/dist/orchestrator/OperatingSystem.js +71 -0
  77. package/dist/orchestrator/OperationalMemoryStore.js +94 -0
  78. package/dist/orchestrator/OptimizationLoop.js +72 -0
  79. package/dist/orchestrator/OrchestrationLoop.js +905 -0
  80. package/dist/orchestrator/OrgStructure.js +88 -0
  81. package/dist/orchestrator/OutcomeSimulator.js +46 -0
  82. package/dist/orchestrator/ParallelOrchestrationLoop.js +36 -0
  83. package/dist/orchestrator/PerformanceScorecard.js +105 -0
  84. package/dist/orchestrator/PlannerAgent.js +46 -0
  85. package/dist/orchestrator/ProcessSandbox.js +129 -0
  86. package/dist/orchestrator/PromotionPipeline.js +74 -0
  87. package/dist/orchestrator/PromotionReviewGate.js +11 -0
  88. package/dist/orchestrator/QueueScheduler.js +260 -0
  89. package/dist/orchestrator/ReleaseGate.js +36 -0
  90. package/dist/orchestrator/ReleaseWorkflow.js +68 -0
  91. package/dist/orchestrator/RemotePublisher.js +139 -0
  92. package/dist/orchestrator/ReuseEngine.js +89 -0
  93. package/dist/orchestrator/ReviewerAgent.js +49 -0
  94. package/dist/orchestrator/RoleHandoff.js +65 -0
  95. package/dist/orchestrator/RuntimeHealthMonitor.js +143 -0
  96. package/dist/orchestrator/RuntimePolicy.js +105 -0
  97. package/dist/orchestrator/RuntimeProbe.js +97 -0
  98. package/dist/orchestrator/RuntimeRegistry.js +73 -0
  99. package/dist/orchestrator/SandboxPolicy.js +22 -0
  100. package/dist/orchestrator/SecurityDownloadGuard.js +169 -0
  101. package/dist/orchestrator/SecurityEventStore.js +58 -0
  102. package/dist/orchestrator/ServiceCompletionPolicy.js +36 -0
  103. package/dist/orchestrator/ServiceState.js +195 -0
  104. package/dist/orchestrator/SkillCreator.js +404 -0
  105. package/dist/orchestrator/SkillLearningLoop.js +57 -0
  106. package/dist/orchestrator/SkillManager.js +75 -0
  107. package/dist/orchestrator/SkillNetwork.js +29 -0
  108. package/dist/orchestrator/SkillRegistryV2.js +28 -0
  109. package/dist/orchestrator/SkillScoring.js +70 -0
  110. package/dist/orchestrator/SquadAutoCreator.js +64 -0
  111. package/dist/orchestrator/SquadCreator.js +727 -0
  112. package/dist/orchestrator/SquadRegistry.js +28 -0
  113. package/dist/orchestrator/SquadRouter.js +33 -0
  114. package/dist/orchestrator/SquadScoring.js +70 -0
  115. package/dist/orchestrator/SubagentLifecycle.js +90 -0
  116. package/dist/orchestrator/SynthesizerAgent.js +48 -0
  117. package/dist/orchestrator/SystemDoctor.js +224 -0
  118. package/dist/orchestrator/TaskExecutor.js +422 -0
  119. package/dist/orchestrator/TeammateBoard.js +61 -0
  120. package/dist/orchestrator/TestHarness.js +184 -0
  121. package/dist/orchestrator/VoiceManager.js +203 -0
  122. package/dist/orchestrator/VoiceRouter.js +89 -0
  123. package/dist/orchestrator/capability/CapabilityGenesisEngine.js +278 -0
  124. package/dist/orchestrator/capability/CapabilityPackParser.js +223 -0
  125. package/dist/orchestrator/capability/CapabilityPackSchema.js +62 -0
  126. package/dist/orchestrator/capability/CapabilityPackState.js +163 -0
  127. package/dist/orchestrator/providers/AgentProvider.js +2 -0
  128. package/dist/orchestrator/providers/CapabilityProvider.js +12 -0
  129. package/dist/orchestrator/providers/CloudAgentProvider.js +55 -0
  130. package/dist/orchestrator/providers/CloudSkillProvider.js +55 -0
  131. package/dist/orchestrator/providers/CloudSquadProvider.js +55 -0
  132. package/dist/orchestrator/providers/CompositeAgentProvider.js +16 -0
  133. package/dist/orchestrator/providers/CompositeCapabilityProvider.js +25 -0
  134. package/dist/orchestrator/providers/CompositeSkillProvider.js +16 -0
  135. package/dist/orchestrator/providers/CompositeSquadProvider.js +16 -0
  136. package/dist/orchestrator/providers/CompositeWorkflowProvider.js +46 -0
  137. package/dist/orchestrator/providers/FileAgentProvider.js +105 -0
  138. package/dist/orchestrator/providers/FileCapabilityProvider.js +106 -0
  139. package/dist/orchestrator/providers/FileSkillProvider.js +65 -0
  140. package/dist/orchestrator/providers/FileSquadProvider.js +69 -0
  141. package/dist/orchestrator/providers/FileWorkflowProvider.js +103 -0
  142. package/dist/orchestrator/providers/SkillProvider.js +2 -0
  143. package/dist/orchestrator/providers/SquadProvider.js +2 -0
  144. package/dist/orchestrator/toolset/ToolsetGuard.js +69 -0
  145. package/dist/orchestrator/toolset/ToolsetRegistry.js +65 -0
  146. package/dist/orchestrator/toolset/ToolsetSchema.js +21 -0
  147. package/dist/orchestrator/util/AtomicWriter.js +204 -0
  148. package/dist/orchestrator/util/DistributedLock.js +232 -0
  149. package/dist/orchestrator/util/TemplateRenderer.js +87 -0
  150. package/dist/orchestrator/util/WatchdogHeartbeat.js +116 -0
  151. package/dist/orchestrator/workflow/ConditionParser.js +232 -0
  152. package/dist/orchestrator/workflow/WorkflowEngine.js +379 -0
  153. package/dist/orchestrator/workflow/WorkflowParser.js +368 -0
  154. package/dist/orchestrator/workflow/WorkflowSchema.js +65 -0
  155. package/dist/orchestrator/workflow/WorkflowState.js +11 -0
  156. package/dist/reversa/ReversaAgent.js +134 -0
  157. package/dist/reversa/ReversaContracts.js +62 -0
  158. package/dist/reversa/ReversaExecutors.js +65 -0
  159. package/dist/skills/SkillRegistry.js +71 -0
  160. package/dist/squads/SquadManager.js +87 -0
  161. package/dist/test_admin_teams_networks.js +54 -0
  162. package/dist/test_agent_team_skill_network.js +15 -0
  163. package/dist/test_aiobuilder_cli_parity.js +169 -0
  164. package/dist/test_ask_exit.js +73 -0
  165. package/dist/test_atomic_writer.js +209 -0
  166. package/dist/test_autonomous_soak.js +141 -0
  167. package/dist/test_benchmark_engine.js +41 -0
  168. package/dist/test_brain_error_diagnostics.js +51 -0
  169. package/dist/test_brain_fallback_chain.js +93 -0
  170. package/dist/test_capability_genesis_engine.js +225 -0
  171. package/dist/test_capability_pack_schema.js +214 -0
  172. package/dist/test_catalog_quality.js +150 -0
  173. package/dist/test_cli_crud_roundtrip.js +154 -0
  174. package/dist/test_cli_diagnostics.js +131 -0
  175. package/dist/test_cli_doc_parity.js +126 -0
  176. package/dist/test_cli_help_surface.js +106 -0
  177. package/dist/test_cli_service_commands.js +83 -0
  178. package/dist/test_consequence_forecast_brain.js +165 -0
  179. package/dist/test_consequence_forecaster.js +24 -0
  180. package/dist/test_conversation_memory.js +36 -0
  181. package/dist/test_create_entities.js +54 -0
  182. package/dist/test_creator_placeholders_completed.js +177 -0
  183. package/dist/test_cron_manager.js +123 -0
  184. package/dist/test_daemon_sigterm.js +72 -0
  185. package/dist/test_deep_research_capability.js +87 -0
  186. package/dist/test_designmd_import_registry.js +16 -0
  187. package/dist/test_designmd_mode.js +50 -0
  188. package/dist/test_designmd_mode_workspace.js +13 -0
  189. package/dist/test_dist_templates_layout.js +135 -0
  190. package/dist/test_distributed_lock.js +201 -0
  191. package/dist/test_distribution_installability.js +67 -0
  192. package/dist/test_doctor_sandbox_check.js +44 -0
  193. package/dist/test_dream_organizer.js +25 -0
  194. package/dist/test_dual_mode.js +15 -0
  195. package/dist/test_enterprise_agentic_core.js +128 -0
  196. package/dist/test_forecast_brain_wiring.js +87 -0
  197. package/dist/test_gateway_telegram_guardrails.js +52 -0
  198. package/dist/test_governance.js +34 -0
  199. package/dist/test_governance_advanced.js +75 -0
  200. package/dist/test_governance_scope_ledger.js +147 -0
  201. package/dist/test_governance_v13_policies.js +44 -0
  202. package/dist/test_guided_creator_cli.js +100 -0
  203. package/dist/test_host_install_e2e.js +324 -0
  204. package/dist/test_host_installer.js +259 -0
  205. package/dist/test_host_installers_gemini_codex.js +95 -0
  206. package/dist/test_host_uninstaller.js +295 -0
  207. package/dist/test_install_flow.js +70 -0
  208. package/dist/test_install_flow_host_validation.js +143 -0
  209. package/dist/test_install_wizard.js +272 -0
  210. package/dist/test_integration_gemini_live.js +95 -0
  211. package/dist/test_integration_http_trigger_live.js +154 -0
  212. package/dist/test_integration_telegram_live.js +102 -0
  213. package/dist/test_job_lifecycle.js +16 -0
  214. package/dist/test_memory_orchestrator.js +33 -0
  215. package/dist/test_memory_promotion.js +36 -0
  216. package/dist/test_memory_retention.js +37 -0
  217. package/dist/test_mission_checkpoint.js +204 -0
  218. package/dist/test_multi_host_docs_parity.js +125 -0
  219. package/dist/test_openlife_auto_creator_routing.js +69 -0
  220. package/dist/test_openlife_evolution_surface.js +77 -0
  221. package/dist/test_openlife_gatekeeper_routing.js +15 -0
  222. package/dist/test_openlife_routing_surface.js +27 -0
  223. package/dist/test_openlife_runtime_source_truth.js +25 -0
  224. package/dist/test_operating_system.js +45 -0
  225. package/dist/test_optimization_loop.js +38 -0
  226. package/dist/test_orchestration_assets_lifecycle.js +78 -0
  227. package/dist/test_outcome_simulator.js +38 -0
  228. package/dist/test_performance_latency.js +215 -0
  229. package/dist/test_performance_scorecard.js +38 -0
  230. package/dist/test_phase1_check_exit.js +103 -0
  231. package/dist/test_phase6_board.js +31 -0
  232. package/dist/test_phase6_cadence.js +29 -0
  233. package/dist/test_phase6_ops.js +37 -0
  234. package/dist/test_post_mission_evaluation.js +190 -0
  235. package/dist/test_process_sandbox.js +88 -0
  236. package/dist/test_profile_toolset_mcp.js +125 -0
  237. package/dist/test_queue_scheduler.js +239 -0
  238. package/dist/test_release_gate.js +23 -0
  239. package/dist/test_remote_publish.js +193 -0
  240. package/dist/test_reversa_contracts_e2e.js +48 -0
  241. package/dist/test_reversa_export_and_strict.js +51 -0
  242. package/dist/test_reversa_full_execution.js +12 -0
  243. package/dist/test_reversa_lite.js +9 -0
  244. package/dist/test_royal_stack_golden.js +179 -0
  245. package/dist/test_runtime_health_backoff.js +154 -0
  246. package/dist/test_runtime_policy.js +26 -0
  247. package/dist/test_runtime_probe.js +19 -0
  248. package/dist/test_runtime_profile_oauth_only.js +262 -0
  249. package/dist/test_runtime_registry.js +11 -0
  250. package/dist/test_security_download_and_scan.js +103 -0
  251. package/dist/test_security_download_guard.js +14 -0
  252. package/dist/test_service_command_surface.js +12 -0
  253. package/dist/test_service_completion_policy.js +32 -0
  254. package/dist/test_service_guardrails_delete.js +12 -0
  255. package/dist/test_service_mode_explicit_only.js +174 -0
  256. package/dist/test_sources_import_ref.js +46 -0
  257. package/dist/test_sources_scaffold.js +43 -0
  258. package/dist/test_squad_skill_creator.js +305 -0
  259. package/dist/test_squad_skill_design_llm.js +176 -0
  260. package/dist/test_subsystems_org_state.js +271 -0
  261. package/dist/test_subsystems_promotion_memory_assets.js +343 -0
  262. package/dist/test_subsystems_routing_governance.js +234 -0
  263. package/dist/test_task_executor_sandbox_optin.js +127 -0
  264. package/dist/test_teammate_learning.js +15 -0
  265. package/dist/test_telegram_delete_guardrail.js +21 -0
  266. package/dist/test_toolset_enforcement.js +188 -0
  267. package/dist/test_trigger_basic_auth.js +112 -0
  268. package/dist/test_util/doc_parity.js +120 -0
  269. package/dist/test_v15_e2e_integration.js +207 -0
  270. package/dist/test_watchdog_heartbeat.js +152 -0
  271. package/dist/test_workflow_condition_parser.js +63 -0
  272. package/dist/test_workflow_e2e.js +240 -0
  273. package/dist/test_workflow_engine.js +330 -0
  274. package/dist/test_workflow_parser.js +245 -0
  275. package/dist/test_workflow_schema_backward_compat.js +197 -0
  276. package/dist-templates/README.md +91 -0
  277. package/dist-templates/claude-code/agents/openlife-atlas.md +52 -0
  278. package/dist-templates/claude-code/agents/openlife-forge.md +42 -0
  279. package/dist-templates/claude-code/agents/openlife-genesis.md +59 -0
  280. package/dist-templates/claude-code/agents/openlife-lyra.md +40 -0
  281. package/dist-templates/claude-code/agents/openlife-maestro.md +45 -0
  282. package/dist-templates/claude-code/commands/openlife/ask.md +14 -0
  283. package/dist-templates/claude-code/commands/openlife/doctor.md +19 -0
  284. package/dist-templates/claude-code/commands/openlife/dream.md +20 -0
  285. package/dist-templates/claude-code/commands/openlife/status.md +14 -0
  286. package/dist-templates/claude-code/mcp/openlife-orchestrator.json +46 -0
  287. package/dist-templates/codex/README.md +7 -0
  288. package/dist-templates/codex/agents/openlife-atlas.md +52 -0
  289. package/dist-templates/codex/agents/openlife-forge.md +42 -0
  290. package/dist-templates/codex/agents/openlife-genesis.md +59 -0
  291. package/dist-templates/codex/agents/openlife-lyra.md +40 -0
  292. package/dist-templates/codex/agents/openlife-maestro.md +45 -0
  293. package/dist-templates/codex/commands/openlife/ask.md +14 -0
  294. package/dist-templates/codex/commands/openlife/doctor.md +19 -0
  295. package/dist-templates/codex/commands/openlife/dream.md +20 -0
  296. package/dist-templates/codex/commands/openlife/status.md +14 -0
  297. package/dist-templates/codex/mcp/openlife-orchestrator.json +46 -0
  298. package/dist-templates/gemini-cli/README.md +8 -0
  299. package/dist-templates/gemini-cli/agents/openlife-atlas.md +52 -0
  300. package/dist-templates/gemini-cli/agents/openlife-forge.md +42 -0
  301. package/dist-templates/gemini-cli/agents/openlife-genesis.md +59 -0
  302. package/dist-templates/gemini-cli/agents/openlife-lyra.md +40 -0
  303. package/dist-templates/gemini-cli/agents/openlife-maestro.md +45 -0
  304. package/dist-templates/gemini-cli/commands/openlife/ask.md +14 -0
  305. package/dist-templates/gemini-cli/commands/openlife/doctor.md +19 -0
  306. package/dist-templates/gemini-cli/commands/openlife/dream.md +20 -0
  307. package/dist-templates/gemini-cli/commands/openlife/status.md +14 -0
  308. package/dist-templates/gemini-cli/mcp/openlife-orchestrator.json +46 -0
  309. package/dist-templates/skill-template/README.md +34 -0
  310. package/dist-templates/skill-template/SKILL.md.template +59 -0
  311. package/dist-templates/squad-template/README.md +82 -0
  312. package/dist-templates/squad-template/SQUAD.md.template +51 -0
  313. package/dist-templates/squad-template/agent-template.md +51 -0
  314. package/dist-templates/squad-template/checklist-template.md +25 -0
  315. package/dist-templates/squad-template/task-template.md +36 -0
  316. package/dist-templates/workflows/PORTED_WORKFLOWS.md +60 -0
  317. package/dist-templates/workflows/brownfield-discovery.yaml +137 -0
  318. package/dist-templates/workflows/greenfield-fullstack.yaml +132 -0
  319. package/dist-templates/workflows/qa-loop.yaml +125 -0
  320. package/dist-templates/workflows/story-development-cycle.yaml +80 -0
  321. package/docs/CHANGELOG_FEATURE_ROLLOUT_DESIGNMD.md +43 -0
  322. package/docs/EXTERNAL_SOURCES_AND_SECURITY_GUARD.md +33 -0
  323. package/docs/OPENLIFE_AUDIT_2026-05-06.md +170 -0
  324. package/docs/OPENLIFE_CONSOLIDATED_PLAN_2026-05-06.md +299 -0
  325. package/docs/OPENLIFE_DUAL_MODE_IMPLEMENTATION_PLAN.md +205 -0
  326. package/docs/OPENLIFE_EVOLUTION_SURFACE_2026-05-07.md +53 -0
  327. package/docs/OPENLIFE_SKILLS_IMPORT_2026-05-07.json +223 -0
  328. package/docs/OPENLIFE_SQUADS_IMPORT_2026-05-07.json +184 -0
  329. package/docs/PAPERCLIP_OPENLIFE_INVESTIGATION.md +85 -0
  330. package/docs/README.md +28 -0
  331. package/docs/RELEASE_ORGANIZATION_PLAN.md +164 -0
  332. package/docs/audit/CLI-EXECUTION-RESULTS.md +113 -0
  333. package/docs/audit/CLI-MATRIX.md +556 -0
  334. package/docs/audit/DOC-PARITY-GAPS.md +351 -0
  335. package/docs/audit/ORCHESTRATOR-MATRIX.md +136 -0
  336. package/docs/audit/TEST-COVERAGE-GAPS.md +334 -0
  337. package/docs/audit/integrations/SKIPPED.md +101 -0
  338. package/docs/autonomous-install.md +79 -0
  339. package/docs/capability-genesis.md +137 -0
  340. package/docs/capability-pack-schema.md +157 -0
  341. package/docs/commands.md +82 -0
  342. package/docs/deep-research-capability.md +114 -0
  343. package/docs/development/typescript-conventions.md +95 -0
  344. package/docs/host-installers.md +68 -0
  345. package/docs/install/aiobuilder.md +70 -0
  346. package/docs/install/claude-code.md +83 -0
  347. package/docs/install/codex.md +64 -0
  348. package/docs/install/gemini-cli.md +64 -0
  349. package/docs/install/runtime-profiles.md +83 -0
  350. package/docs/openlife-agent-os-blueprint.md +114 -0
  351. package/docs/openlife-install-backlog.md +115 -0
  352. package/docs/openlife-install-spec.md +306 -0
  353. package/docs/operations/CLOUD_CUTOVER_AUDIT.md +37 -0
  354. package/docs/operations/PHASE_PROGRESS_CONTINUATION.md +24 -0
  355. package/docs/performance-benchmarks.md +83 -0
  356. package/docs/planning/v1.3-capability-genesis.md +157 -0
  357. package/docs/plans/2026-05-05-admin-interface-professional-dark-premium-plan.md +84 -0
  358. package/docs/plans/2026-05-05-openlife-autonomous-domain-marketplace-masterplan.md +122 -0
  359. package/docs/quickstart.md +60 -0
  360. package/docs/release-process.md +236 -0
  361. package/docs/roadmap/OPENLIFE_MASTER_PLAN_CLOUD_V3.md +97 -0
  362. package/docs/sandboxing-research.md +117 -0
  363. package/docs/stories/epic-feature-audit/1.1.story.md +84 -0
  364. package/docs/stories/epic-feature-audit/1.2.story.md +102 -0
  365. package/docs/stories/epic-feature-audit/1.3.story.md +93 -0
  366. package/docs/stories/epic-feature-audit/1.5.story.md +121 -0
  367. package/docs/stories/epic-feature-audit/1.6.story.md +80 -0
  368. package/docs/stories/epic-feature-completeness/2.1.story.md +70 -0
  369. package/docs/stories/epic-feature-completeness/2.2.story.md +49 -0
  370. package/docs/stories/epic-feature-completeness/2.3.story.md +74 -0
  371. package/docs/stories/epic-feature-completeness/2.4.story.md +71 -0
  372. package/docs/stories/epic-feature-completeness/3.1.story.md +56 -0
  373. package/docs/stories/epic-feature-completeness/3.2.story.md +80 -0
  374. package/docs/stories/epic-feature-completeness/3.3.story.md +68 -0
  375. package/docs/stories/epic-feature-completeness/3.4.story.md +71 -0
  376. package/docs/stories/epic-feature-completeness/3.5.story.md +72 -0
  377. package/docs/stories/epic-feature-completeness/3.6.story.md +69 -0
  378. package/docs/stories/epic-feature-completeness/3.7.story.md +68 -0
  379. package/docs/stories/epic-feature-completeness/3.8.story.md +57 -0
  380. package/docs/toolset-enforcement.md +122 -0
  381. package/docs/v1.4-changelog.md +159 -0
  382. package/docs/v1.5-changelog.md +106 -0
  383. package/docs/v1.5-roadmap.md +121 -0
  384. package/docs/v1.6-changelog.md +67 -0
  385. package/docs/v1.6-roadmap.md +89 -0
  386. package/docs/v1.7-changelog.md +98 -0
  387. package/docs/workflow-schema.md +177 -0
  388. package/package.json +177 -0
  389. package/scripts/clean-test-pollution.js +61 -0
  390. package/scripts/openlife-agent-start.sh +6 -0
  391. package/scripts/openlife-agent.service.example +13 -0
  392. package/scripts/openlife-agent.supervisord.conf.example +8 -0
  393. package/scripts/openlife-autonomous-install.sh +29 -0
  394. package/scripts/postinstall-check.sh +37 -0
@@ -0,0 +1,74 @@
1
+ # Story 2.3 — [CONCERN] `pilot/learning/plugin --help` >3s (NOT REPRODUCIBLE)
2
+
3
+ **StoryId:** `2.3`
4
+ **Epic:** `epic-feature-completeness`
5
+ **Status:** Closed (No-Fix Required — concern did not reproduce)
6
+ **Severity:** P3
7
+ **Discovered in:** Phase 2 of total feature audit (`.planning/phase-2/FINDINGS.md` CONCERN-01)
8
+ **Cluster:** lazy-load-performance
9
+
10
+ ## Description
11
+
12
+ Phase 2 test `test_cli_help_surface.ts` flagged 3 command groups with `--help` latency >3s:
13
+ - `pilot --help` — 4175ms
14
+ - `learning --help` — 3311ms
15
+ - `plugin --help` — 3249ms
16
+
17
+ Original hypothesis: top-level imports of heavy classes (EnterpriseAgenticCore, SkillLearningLoop) violating the lazy-load invariant documented in `CLAUDE.md`.
18
+
19
+ ## Investigation (2026-05-11)
20
+
21
+ Direct measurement after Stories 2.1 + 2.2:
22
+
23
+ ```
24
+ pilot --help: 1336ms
25
+ learning --help: 1417ms
26
+ plugin --help: 1589ms
27
+ help --help: 1392ms
28
+ install --help: 1625ms
29
+ ask --help: 1430ms
30
+ system --help: 1368ms
31
+ ```
32
+
33
+ All groups respond to `--help` in ~1.3–1.6s, **uniform across the surface**. No outliers.
34
+
35
+ Re-running `test_cli_help_surface.ts`:
36
+
37
+ ```
38
+ TEST_CLI_HELP_SURFACE_OK (45/45 groups + 2 root invocations)
39
+ ```
40
+
41
+ No `SLOW (>3s)` line — meaning all 45 groups + 2 root invocations now complete under the 3s threshold.
42
+
43
+ Module load timings (isolated):
44
+ - `require('./orchestrator/EnterpriseAgenticCore')`: **21ms**
45
+ - `require('./orchestrator/SkillLearningLoop')`: same range
46
+
47
+ These are NOT heavy modules. The original "slow" reading was a measurement artifact — likely subprocess startup batching in the first few test iterations, or transient system load during the Phase 2 baseline.
48
+
49
+ ## Decision
50
+
51
+ **NO-FIX REQUIRED.** Concern was a false positive in the Phase 2 baseline measurement.
52
+
53
+ Action items:
54
+ - [x] Re-measure with current build — all `--help` <2s
55
+ - [x] Re-run `test_cli_help_surface.ts` — no SLOW flags
56
+ - [x] Document finding here for traceability
57
+ - [x] Update `.planning/phase-2/FINDINGS.md` to note CONCERN-01 resolved
58
+
59
+ **If future regression** brings `--help` back over 3s for any group: re-open this story. The test still has the 3s threshold and will flag.
60
+
61
+ ## Acceptance Criteria
62
+
63
+ - [x] No production code changes
64
+ - [x] `npm run test:all` continues green (63/63)
65
+ - [x] CONCERN-01 documented as not-reproducible
66
+
67
+ ## File List
68
+
69
+ - `docs/stories/epic-feature-completeness/2.3.story.md` — NEW (this story)
70
+ - `.planning/phase-2/FINDINGS.md` — MODIFIED (CONCERN-01 marked resolved)
71
+
72
+ ## Change Log
73
+
74
+ - 2026-05-11 — @dev (Charlie) — Investigated CONCERN-01. Not reproducible with current build (~1.4s help latency uniform). Closed as No-Fix.
@@ -0,0 +1,71 @@
1
+ # Story 2.4 — [DEBT] Test infra cleanup via pretest hook
2
+
3
+ **StoryId:** `2.4`
4
+ **Epic:** `epic-feature-completeness`
5
+ **Status:** InReview
6
+ **Severity:** P3
7
+ **Discovered in:** Phase 2 of total feature audit (`.planning/phase-2/FINDINGS.md` DEBT-01) + `.planning/codebase/CONCERNS.md` C8
8
+ **Cluster:** test-hygiene
9
+
10
+ ## Description
11
+
12
+ Pre-existing test pollution made `npm run test:all` intermittently fail:
13
+ - `test_openlife_evolution_surface` asserts `.catalog/` clean of demo/test artifacts; broken when leftover `test-agent/`, `test-squad/`, `test-skill-*/`, `test-mcp/` persist from prior runs
14
+ - `test_operating_system` sensitive to stale state in `.artifacts/execution-board.json` from older mission runs
15
+ - `test_create_entities`, `test_admin_teams_networks`, `test_sources_import_ref` are the **emitters** of test-* entries (per Story 1.4 Dev Notes)
16
+
17
+ This blocked test:all consistency until manually cleaned. Documented as a "Known Bug" workaround in Phase 2 CLI-EXECUTION-RESULTS.md.
18
+
19
+ ## Reproduce
20
+
21
+ ```bash
22
+ npm run test:all # passes
23
+ npm run test:all # FAILS at test_openlife_evolution_surface ("catalog doctor warns about demo/test assets")
24
+ ```
25
+
26
+ Without `pretest:all` hook, the second run sees the residue from the first.
27
+
28
+ ## Fix
29
+
30
+ Add `scripts/clean-test-pollution.js` + `pretest:all` npm hook that runs **before** `test:all`:
31
+
32
+ 1. Remove `.catalog/{agents,squads,skills,mcps}/test-*` (and `void` directory auto-created)
33
+ 2. Delete `.artifacts/` recursively
34
+ 3. Restore tracked `.artifacts/*` files via `git checkout -- .artifacts/`
35
+ 4. Idempotent (safe to run multiple times)
36
+
37
+ This is a **pragmatic mitigation** that unblocks test:all NOW. Proper fix (deferred to Story 2.4 v2 in v2.0+) is `OPENLIFE_CATALOG_DIR` env override + temp-dir fixtures in offending tests.
38
+
39
+ ## Acceptance Criteria
40
+
41
+ - [x] `scripts/clean-test-pollution.js` exists, executable, idempotent
42
+ - [x] `package.json` has `pretest:all` script invoking the cleanup
43
+ - [x] `npm run test:all` runs cleanup automatically before tests
44
+ - [x] `npm run test:all` passes 2+ consecutive runs (deterministic)
45
+ - [x] Cleanup script preserves tracked files (e.g., `.artifacts/squad-scores.json`)
46
+ - [x] `npm run test:all` = 63/63 verde
47
+ - [x] `pretest:all` output visible in stdout (operators see what was cleaned)
48
+
49
+ ## Dev Notes
50
+
51
+ - **Why not `OPENLIFE_CATALOG_DIR` override now?** Would require changes to 3 separate env var conventions (`OPENLIFE_AGENT_ROOTS`, `OPENLIFE_SKILL_ROOT`, `OPENLIFE_SQUAD_ROOT`), plus offending tests need refactor. ~6-10h effort vs ~30min for this hook approach. Hook unblocks immediately; env override can ship in v2.0 epic F (test parallelization).
52
+ - **Patterns cleaned:** `test-*` prefix + `void` directory (one of the assets agents auto-creates).
53
+ - **`.artifacts/` is gitignored** but `squad-scores.json` is tracked — the cleanup script handles this via `git checkout`.
54
+
55
+ ## File List
56
+
57
+ - `scripts/clean-test-pollution.js` — NEW (executable cleanup script)
58
+ - `package.json` — MODIFIED (added `pretest:all` hook)
59
+
60
+ ## Change Log
61
+
62
+ - 2026-05-11 — @dev (Charlie) — Added pretest cleanup hook. test:all now deterministic across consecutive runs. Status: Ready → InReview.
63
+
64
+ ## IDS check
65
+
66
+ **Decision:** CREATE (new ops script).
67
+
68
+ ## Future work (out of this story)
69
+
70
+ - Story 2.4-v2 (v2.0 epic F): `OPENLIFE_CATALOG_DIR` env override + temp-dir fixtures in test_create_entities/test_admin_teams_networks/test_sources_import_ref
71
+ - Story 2.4-v3 (v2.0): pretest hook on individual test scripts (not just test:all)
@@ -0,0 +1,56 @@
1
+ # Story 3.1 — Host enum + validator (v1.1 multi-host installer foundation)
2
+
3
+ **StoryId:** `3.1`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P1 (foundational — blocks 3.2-3.7)
7
+ **Cluster:** install-flow
8
+
9
+ ## Description
10
+
11
+ `InstallFlow.run({ host })` currently accepts ANY string and ignores it. This is the architectural stub identified in the comprehensive codebase audit (2026-05-11): "Host install is architectural stub". For v1.1 to deliver real multi-host install, we need a validated type so downstream stories (per-host logic, MCP registration, docs) have a deterministic input.
12
+
13
+ ## Acceptance Criteria
14
+
15
+ - [x] **Type** `Host = 'claude-code' | 'gemini-cli' | 'codex'` exported from `src/cli/InstallFlow.ts`
16
+ - [x] **Constants** `VALID_HOSTS` and `DEFAULT_HOST` exported
17
+ - [x] **Function** `validateHost(value)` — throws `INVALID_HOST` with clear message + valid list when input is invalid; falls back to `DEFAULT_HOST` on null/undefined/empty
18
+ - [x] **Case-insensitive** + whitespace-tolerant validation (`CLAUDE-CODE`, ` Codex ` normalize)
19
+ - [x] **Auto-detection** `detectHostFromEnv()` based on env vars set by each CLI:
20
+ - `claude-code` ← `CLAUDECODE` or `CLAUDE_PROJECT_DIR`
21
+ - `gemini-cli` ← `GEMINI_CONFIG_DIR`
22
+ - `codex` ← `CODEX_HOME`
23
+ - [x] `InstallFlow.run()` uses validateHost — invalid host throws clear error
24
+ - [x] Fixed deprecated `mode set` reference in `buildNextCommands` (replaced with `system setup --profile X --host Y`, mirror of commit `aba599b` INSTALL.md fix)
25
+ - [x] Regression test `src/test_install_flow_host_validation.ts` — 7 test cases covering happy path + edge cases
26
+ - [x] Suite 63 → 64 verde
27
+ - [x] Bumped `test_ask_exit` timeout 30s → 60s (pre-existing latency margin, not a regression)
28
+
29
+ ## Dev Notes
30
+
31
+ - **Why all 3 hosts now (not just claude-code)?** Decision D3 locked: install offers Lone Wolf or Swarm Commander × any of 3 hosts. Story 3.1 establishes the enum so 3.2 (templates) and 3.3 (per-host logic) have a stable type to branch on.
32
+ - **Why case-insensitive + trim?** Real users mistype. `--host Claude-Code` should work.
33
+ - **Auto-detection priority** picks the most specific signal. If user sets both `CLAUDECODE=1` and `GEMINI_CONFIG_DIR=/x`, we pick claude-code (declared first). Tests cover both paths but not the conflict — operators are expected to set one or pass `--host` explicitly.
34
+ - **Fixing `mode set` in nextCommands** was a drive-by — same class of bug as 3 CRITICAL doc gaps closed in commit `aba599b`. The `buildNextCommands` output was still telling users to run a non-existent command. Now uses `system setup`.
35
+
36
+ ## File List
37
+
38
+ - `src/cli/InstallFlow.ts` — MODIFIED (added Host type, validateHost, detectHostFromEnv, VALID_HOSTS, DEFAULT_HOST; updated `run()` to validate; updated `buildNextCommands` to use real command)
39
+ - `src/test_install_flow_host_validation.ts` — NEW (7 test cases)
40
+ - `src/test_ask_exit.ts` — MODIFIED (timeout 30s → 60s, comment explains why)
41
+ - `package.json` — MODIFIED (added `test:install-flow-host-validation`, appended to `test:all`)
42
+
43
+ ## Change Log
44
+
45
+ - 2026-05-11 — @dev (Charlie) — Implemented host enum + validator + auto-detection + bug fix on buildNextCommands. test:all 63 → 64 verde. Status: Ready → InReview.
46
+
47
+ ## IDS check
48
+
49
+ **Decision:** ADAPT (extending existing InstallFlow with stricter typing) + CREATE (regression test).
50
+
51
+ ## What unblocks for v1.1
52
+
53
+ - Story 3.2 (templates per host) — has `Host` type to switch on
54
+ - Story 3.3 (per-host install logic) — has `validateHost` at CLI boundary
55
+ - Story 3.4 (uninstall) — has same enum for reversal
56
+ - Story 3.5 (wizard) — has detection + validation primitives
@@ -0,0 +1,80 @@
1
+ # Story 3.2 — dist-templates per host (Claude Code starter roster)
2
+
3
+ **StoryId:** `3.2`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P1 (blocks 3.3 per-host install logic)
7
+ **Cluster:** install-flow
8
+ **Depends on:** Story 3.1 (host enum + validator)
9
+
10
+ ## Description
11
+
12
+ Story 3.1 gave OpenLife a validated `Host` type at the CLI boundary, but `openlife system setup --host claude-code` had nothing to install. We need the actual artifacts — agent files, slash commands, MCP manifest — bundled in the npm package so install is offline and atomic.
13
+
14
+ This story ships the **Claude Code** templates only. gemini-cli and codex follow in Story 3.3 once each host's installation format is investigated and verified.
15
+
16
+ ## Acceptance Criteria
17
+
18
+ - [x] **Directory layout** `dist-templates/claude-code/{agents,commands/openlife,mcp}` exists in the repo
19
+ - [x] **5 starter agents** in Claude Code subagent format (YAML frontmatter + system prompt body):
20
+ - `openlife-maestro` — meta-orchestrator (routes to specialists via `Task` tool)
21
+ - `openlife-lyra` — research synthesis + narrative writing
22
+ - `openlife-forge` — artifact creation (agents, skills, slash commands, MCP)
23
+ - `openlife-atlas` — codebase mapping + architectural analysis
24
+ - `openlife-genesis` — new-project bootstrap + install/scaffold
25
+ - [x] **4 starter slash commands** under `commands/openlife/`:
26
+ - `/openlife:status`, `/openlife:ask`, `/openlife:doctor`, `/openlife:dream`
27
+ - [x] **MCP manifest** `mcp/openlife-orchestrator.json` with 7 tool declarations (server impl deferred to Story 3.3)
28
+ - [x] **README** `dist-templates/README.md` documenting layout, format, and how to add new agents
29
+ - [x] `package.json` `files` array includes `dist-templates/` (so npm publishes it)
30
+ - [x] **Regression test** `src/test_dist_templates_layout.ts` — 5 test groups: layout, agents parse, slash commands parse, MCP valid JSON, package.json correctness
31
+ - [x] Test wired into `test:all`; suite 64 → 65 verde
32
+
33
+ ## Dev Notes
34
+
35
+ - **Why 5 agents, not 21?** User chose "Pulled from 21 vault agents (MAESTRO/LYRA/etc.)" approach. Starter set is the 5 with clearest non-overlapping ownership: MAESTRO (routing), LYRA (synthesis), FORGE (creation), ATLAS (analysis), GENESIS (bootstrap). Remaining 16 are scheduled for v1.1+ stories once each role has a verified `.catalog/agents/` runtime counterpart.
36
+ - **Why Claude Code format only?** User chose "Claude Code primeiro (Recomendado)" — Claude Code's subagent spec is well-documented and the most mature host. gemini-cli/codex defer to Story 3.3 to investigate their respective formats.
37
+ - **Why is the MCP server stubbed?** The manifest ships so install is atomic (single host-add operation copies all artifacts), but `bin/openlife-mcp.js` doesn't exist yet. Story 3.3 wires up the actual MCP server. Until then, the manifest is informational — installing it into `~/.claude.json` is harmless.
38
+ - **dist-templates vs .catalog/.** Two different audiences:
39
+ - `.catalog/agents/` = OpenLife **runtime** catalog (rich YAML, loaded by `AgentRegistry`)
40
+ - `dist-templates/claude-code/agents/` = what gets **installed into the host CLI** (lean Claude Code subagent format)
41
+ - Same logical agent can appear in both with different formats.
42
+ - **Lean prompt size.** Each agent file is ~50-80 lines including frontmatter. Compare to legacy heavy-format runtime catalog entries (~330 lines). Claude Code agents work best with focused system prompts; verbose persona definitions are wasted context per invocation.
43
+
44
+ ## File List
45
+
46
+ - `dist-templates/README.md` — NEW (layout + format docs)
47
+ - `dist-templates/claude-code/agents/openlife-maestro.md` — NEW
48
+ - `dist-templates/claude-code/agents/openlife-lyra.md` — NEW
49
+ - `dist-templates/claude-code/agents/openlife-forge.md` — NEW
50
+ - `dist-templates/claude-code/agents/openlife-atlas.md` — NEW
51
+ - `dist-templates/claude-code/agents/openlife-genesis.md` — NEW
52
+ - `dist-templates/claude-code/commands/openlife/status.md` — NEW
53
+ - `dist-templates/claude-code/commands/openlife/ask.md` — NEW
54
+ - `dist-templates/claude-code/commands/openlife/doctor.md` — NEW
55
+ - `dist-templates/claude-code/commands/openlife/dream.md` — NEW
56
+ - `dist-templates/claude-code/mcp/openlife-orchestrator.json` — NEW
57
+ - `src/test_dist_templates_layout.ts` — NEW (5 test groups, 65th test in suite)
58
+ - `package.json` — MODIFIED (added `dist-templates` to `files`; added `test:dist-templates-layout` script; appended to `test:all`)
59
+
60
+ ## Change Log
61
+
62
+ - 2026-05-11 — @dev (Charlie) — Created dist-templates/ skeleton with 5 starter agents (MAESTRO/LYRA/FORGE/ATLAS/GENESIS) in Claude Code subagent format, 4 starter slash commands under `/openlife:*`, MCP manifest (server stubbed for 3.3), regression test, README. test:all 64 → 65 verde. Status: Ready → InReview.
63
+
64
+ ## IDS check
65
+
66
+ **Decision:** CREATE (new distribution surface — no existing artifact installs templates into a host CLI). Format follows Claude Code's published subagent + slash command spec (REUSE of external pattern, not invented).
67
+
68
+ ## What unblocks for v1.1
69
+
70
+ - Story 3.3 (per-host install logic) — has templates to copy
71
+ - Story 3.4 (uninstall reversible) — has known artifact list to remove
72
+ - Story 3.5 (install wizard interactive) — has roster to present to user
73
+ - Story 3.6 (docs per host) — has agent/command surface to document
74
+
75
+ ## What this does NOT do
76
+
77
+ - Implement the actual MCP server (`bin/openlife-mcp.js`) → Story 3.3
78
+ - Ship gemini-cli or codex templates → Story 3.3
79
+ - Wire `InstallFlow.run()` to actually copy these into the host → Story 3.3
80
+ - Add the remaining 16 named agents (VEIN/FLUX/VECTOR/etc.) → spread across v1.1+ stories
@@ -0,0 +1,68 @@
1
+ # Story 3.3 — Per-host install logic (Claude Code wiring, gemini-cli/codex stubbed)
2
+
3
+ **StoryId:** `3.3`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P1 (closes the "host install is architectural stub" finding)
7
+ **Cluster:** install-flow
8
+ **Depends on:** Story 3.1 (host enum + validator), Story 3.2 (dist-templates Claude Code starter roster)
9
+
10
+ ## Description
11
+
12
+ Story 3.1 validated the `Host` type at the CLI boundary and Story 3.2 shipped the artifacts under `dist-templates/claude-code/`. But `openlife system setup --host claude-code` still did nothing host-specific — `InstallFlow.run()` ended after `SystemInstaller.install()` wrote the OpenLife state, never touching the host CLI's expected paths. This story closes the architectural stub for **claude-code** and lays the dispatch surface for the other two hosts.
13
+
14
+ `HostInstaller.install(host, options)` is the new seam. For `claude-code` it copies agent files and slash commands from `dist-templates/` into `<targetRoot>/.claude/{agents,commands/openlife}/` and stages the MCP manifest at `<targetRoot>/.openlife/install-mcp-snippet.json`. For `gemini-cli` and `codex` it throws `HostNotYetSupportedError` with code `HOST_NOT_YET_SUPPORTED` — `InstallFlow.run()` catches this and reports a skipped host instead of aborting the install.
15
+
16
+ ## Acceptance Criteria
17
+
18
+ - [x] **New file** `src/cli/HostInstaller.ts` with class `HostInstaller`, methods `install(host, options)`, `installForClaudeCode`, `installForGeminiCli`, `installForCodex`, and exported `HostNotYetSupportedError`
19
+ - [x] **Claude Code wiring** copies `dist-templates/claude-code/agents/*.md` → `<targetRoot>/.claude/agents/` and `dist-templates/claude-code/commands/openlife/*.md` → `<targetRoot>/.claude/commands/openlife/`
20
+ - [x] **MCP manifest staged** at `<targetRoot>/.openlife/install-mcp-snippet.json` (non-invasive — operator merges into `~/.claude.json` manually; we do not auto-mutate the user's global config)
21
+ - [x] **Idempotency:** identical content returns `skipped-identical`, different content writes `<file>.bak` then overwrites and returns `updated`
22
+ - [x] **`gemini-cli` / `codex`** throw `HostNotYetSupportedError` with code `HOST_NOT_YET_SUPPORTED` and a message pointing at `--host claude-code`
23
+ - [x] **`InstallFlow.run()`** calls `HostInstaller.install()` after `SystemInstaller.install()`, catches `HostNotYetSupportedError`, and degrades gracefully (records skipped host in the result, install does not abort)
24
+ - [x] **`defaultTemplatesRoot()`** resolves relative to the compiled file so it works in both repo-dev (`dist/cli/HostInstaller.js`) and consumer (`node_modules/@open-life/cli/dist/cli/HostInstaller.js`) layouts
25
+ - [x] **Regression test** `src/test_host_installer.ts` covers 7 scenarios: claude-code happy path, idempotent re-install, `.bak` on conflict, MCP snippet staged, missing templates root throws clearly, `gemini-cli` throws `HOST_NOT_YET_SUPPORTED`, `codex` throws `HOST_NOT_YET_SUPPORTED`
26
+ - [x] Test wired into `test:all`; suite 65 → 66 verde
27
+
28
+ ## Dev Notes
29
+
30
+ - **Why stage the MCP manifest instead of editing `~/.claude.json`?** Mutating a global config the user owns is a security/UX trap — one bad merge and we wreck their other MCP servers. Staging the snippet at `<targetRoot>/.openlife/install-mcp-snippet.json` plus a clear `notes[]` entry lets the operator merge with eyes open. Auto-merge is a separate v1.1 story with its own consent flow.
31
+ - **Why does `installForClaudeCode` not recurse into subdirectories?** Claude Code's `.claude/agents/` and `.claude/commands/<namespace>/` layouts are flat by design (one file per agent, one file per command). `copyDir` walks one level on purpose — if a future host needs nested layouts, that host gets its own copy strategy rather than complicating this one.
32
+ - **Why `HostNotYetSupportedError` instead of returning a skipped result?** The dispatcher (`install()`) is the right place to enforce coverage. A thrown error with a stable `code` is unambiguous for `InstallFlow.run()`'s `catch` block and for downstream callers (wizard in 3.5, uninstall in 3.4). Silent returns would let bugs slip through where a host appears "installed" but actually noop'd.
33
+ - **Why `.bak` instead of refusing to overwrite?** Operators re-running `system setup` after editing dist-templates need a path forward without manually moving files. One backup per file is enough — the test asserts the backup contains the prior content, so anyone investigating after an install knows where their custom edits went.
34
+ - **MCP server is still deferred.** `bin/openlife-mcp.js` (the actual stdio server backing the 7 tool declarations in `openlife-orchestrator.json`) is **not** part of this story. The manifest is informational until a later v1.1 story implements the server. The `notes[]` entry in the install result spells this out so operators don't expect tools to light up after a merge.
35
+ - **Why catch `HostNotYetSupportedError` in `InstallFlow.run()` instead of letting it bubble?** Profile selection (Lone Wolf / Swarm Commander) and host selection are independent axes. Failing the entire install because the operator picked `--host gemini-cli` while the rest of `SystemInstaller.install()` succeeded would force them to redo `.openlife/` setup. Graceful skip + clear message is the right contract until 3.3-followup ships gemini-cli/codex installers.
36
+
37
+ ## File List
38
+
39
+ - `src/cli/HostInstaller.ts` — NEW (class, dispatcher, claude-code installer, copyDir/copyFile helpers, `HostNotYetSupportedError`)
40
+ - `src/cli/InstallFlow.ts` — MODIFIED (calls `HostInstaller.install()` after `SystemInstaller.install()`; catches `HostNotYetSupportedError`; threads result into the install summary)
41
+ - `src/test_host_installer.ts` — NEW (7 test scenarios, 66th test in suite)
42
+ - `package.json` — MODIFIED (added `test:host-installer` script; appended to `test:all`)
43
+
44
+ ## Change Log
45
+
46
+ - 2026-05-11 — @dev (Charlie) — Implemented `HostInstaller` with claude-code wiring (agents + slash commands + staged MCP manifest), idempotency via `.bak` on conflict, and `HostNotYetSupportedError` for gemini-cli/codex. `InstallFlow.run()` now catches the not-yet-supported error and degrades gracefully. test:all 65 → 66 verde. Status: Ready → InReview.
47
+
48
+ ## IDS check
49
+
50
+ **Decision:** CREATE (new file-copy installer — no prior artifact wires `dist-templates/` into a host) + ADAPT (`InstallFlow.run()` extended to invoke the new installer and handle its scoped error). Idempotency pattern (`identical → skip`, `differ → .bak + overwrite`) follows `SystemInstaller`'s existing write semantics — REUSE of internal convention.
51
+
52
+ ## What unblocks for v1.1
53
+
54
+ - Story 3.4 (uninstall reversible) — has a known list of written paths to reverse and `.bak` files to restore
55
+ - Story 3.5 (install wizard interactive) — can call `HostInstaller.install()` after presenting the host roster
56
+ - Story 3.6 (docs per host) — `claude-code` is now real; docs can show concrete paths under `.claude/agents/` and `.claude/commands/openlife/`
57
+ - Story 3.7 (gemini-cli + codex installers) — the dispatcher slot is wired; each host just needs its `installForX` body and a templates subdir
58
+ - Story 3.8+ (MCP server `bin/openlife-mcp.js`) — manifest is already staged; server implementation can land without changing the install contract
59
+
60
+ ## What this does NOT do
61
+
62
+ - Implement `bin/openlife-mcp.js` (the MCP server itself) → deferred to a later v1.1 story
63
+ - Ship `gemini-cli` or `codex` installers → those throw `HOST_NOT_YET_SUPPORTED` by design; a later 3.7 wires them
64
+ - Auto-merge the staged MCP snippet into `~/.claude.json` → out of scope; operator merges manually
65
+ - Recurse into subdirectories when copying templates → host layouts are flat by design; revisit if a future host needs nested
66
+ - Uninstall / reverse the file copy → Story 3.4
67
+ - Interactive wizard for host selection → Story 3.5
68
+ - Documentation updates beyond this story file → Story 3.6
@@ -0,0 +1,71 @@
1
+ # Story 3.4 — Per-host uninstall logic (reversible, scoped, `.bak` restore)
2
+
3
+ **StoryId:** `3.4`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P1 (closes the "install is one-way" finding from 3.3 review)
7
+ **Cluster:** install-flow
8
+ **Depends on:** Story 3.3 (host install dispatcher + claude-code wiring)
9
+
10
+ ## Description
11
+
12
+ Story 3.3 made `openlife system setup --host claude-code` write real artifacts into `<targetRoot>/.claude/{agents,commands/openlife}/` and stage an MCP manifest at `<targetRoot>/.openlife/install-mcp-snippet.json`. There was no symmetric reversal — an operator who wanted to remove OpenLife from a host CLI had to manually delete files and remember which ones we owned. This story closes that gap.
13
+
14
+ `HostInstaller.uninstall(host, options)` is the new seam, mirroring `install()`. For `claude-code` it removes **only** the artifacts Story 3.3 wrote: the five `openlife-*.md` agents (prefix-scoped), the entire `commands/openlife/` namespace directory, and the staged MCP snippet. If a `.bak` sits next to a removed agent, it is restored as the original filename — Story 3.3's overwrite is reversed, the user's customization survives. `gemini-cli` and `codex` throw `HostNotYetSupportedError` with code `HOST_NOT_YET_SUPPORTED`, same contract as install. A new CLI command `openlife system uninstall --host <host>` calls the dispatcher and prints JSON.
15
+
16
+ ## Acceptance Criteria
17
+
18
+ - [x] **New methods** on `HostInstaller`: `uninstall(host, options): HostUninstallResult`, `uninstallForClaudeCode`, `uninstallForGeminiCli`, `uninstallForCodex` — symmetric to the install side
19
+ - [x] **Prefix-scoped agent removal:** only files matching `openlife-*.md` in `<targetRoot>/.claude/agents/` are touched. Any file in that directory without the `openlife-` prefix is preserved (user-owned)
20
+ - [x] **Namespaced commands removal:** the entire `<targetRoot>/.claude/commands/openlife/` directory is removed (OpenLife owns the whole namespace by design — 3.3 staged 4 files there)
21
+ - [x] **MCP snippet removal:** `<targetRoot>/.openlife/install-mcp-snippet.json` is deleted if present
22
+ - [x] **`.bak` restore over deletion:** when removing an `openlife-*.md` agent, if a sibling `<file>.bak` exists, it is renamed back to the original filename (restoring the user's pre-3.3 content) instead of being deleted along with the install
23
+ - [x] **`.openlife/` state preserved:** the runtime state directory itself (governance consents, mission state, registry data) is NOT removed. Only the single staged snippet file is. Full purge is a future `--purge` story
24
+ - [x] **`~/.claude.json` untouched:** Story 3.3 never auto-merged into the user's global config, so uninstall makes no attempt to remove anything from it (would be a security/UX trap with no symmetric write)
25
+ - [x] **`gemini-cli` / `codex`** throw `HostNotYetSupportedError` with code `HOST_NOT_YET_SUPPORTED` and a message pointing at `--host claude-code`
26
+ - [x] **New CLI command** `openlife system uninstall --host <host>` registered in `src/index.ts`, uses `require('./cli/HostInstaller')` per the lazy-import contract (`src/index.ts:11-13`), prints `JSON.stringify(result, null, 2)`, sets `process.exitCode = 1` on `HOST_NOT_YET_SUPPORTED`
27
+ - [x] **Idempotent:** running uninstall on an already-clean target returns a result where every file action is `skipped-not-found`. No errors thrown
28
+ - [x] **Regression test** `src/test_host_uninstaller.ts` covers 8 scenarios: claude-code happy path (removes 5 agents + 4 commands + snippet), idempotent re-uninstall, `.bak` restoration when present, user-owned non-prefixed file preservation, `.openlife/` directory survives, snippet-only removal (no agents installed), `gemini-cli` throws, `codex` throws
29
+ - [x] Test wired into `test:all`; suite 66 → 67 verde
30
+
31
+ ## Dev Notes
32
+
33
+ - **Why prefix-scoped removal instead of a manifest?** A written manifest at install time (`.openlife/install-manifest.json`) would be more precise, but it adds a second source of truth that can desync if the user manually moves files. The `openlife-` prefix is the contract: 3.3 only writes prefixed agent files, so 3.4 only removes prefixed agent files. The commands directory is namespaced (`commands/openlife/`), so the whole directory is fair game. No manifest needed.
34
+ - **Why restore `.bak` instead of deleting the install file?** A `.bak` next to an `openlife-*.md` is evidence Story 3.3 overwrote a user edit (per the `copyFile` semantics in `HostInstaller.ts:154-172`). Deleting both would silently throw away the user's prior content. Renaming the `.bak` back to the original filename reverses 3.3's overwrite cleanly — install was a no-op for that file, uninstall restores it to pre-3.3 state. This is the symmetric inverse of 3.3's behavior.
35
+ - **Why preserve `.openlife/`?** Runtime state (governance consents, mission state, registry data, learning loop history) is a separate concern from "is OpenLife wired into this host CLI". An operator who runs `system uninstall --host claude-code` to switch hosts should not lose their governance ledger. Full wipe needs its own story with explicit consent — see "What this does NOT do".
36
+ - **Why not touch `~/.claude.json`?** 3.3 deliberately staged the MCP snippet at `<targetRoot>/.openlife/install-mcp-snippet.json` instead of auto-merging into `~/.claude.json` (security/UX trap with no rollback). Since we never wrote there, we cannot safely remove from there either — we do not know which entry under `mcpServers` came from us vs. the user's other servers. Operator removes manually, same as the install side.
37
+ - **Why throw `HostNotYetSupportedError` on the unsupported hosts instead of returning a skipped result?** Same rationale as 3.3 (`docs/stories/epic-feature-completeness/3.3.story.md:32`): the dispatcher is the right place to enforce coverage. A stable error code is unambiguous for downstream callers (wizard in 3.5, future automation). Silent returns would let bugs slip through where uninstall appears to succeed but actually noop'd.
38
+ - **Why a new CLI command instead of extending `system setup`?** Install and uninstall are independent verbs operators reach for at different times. A `system setup --uninstall` flag would conflate two flows and complicate the install wizard in 3.5. Separate command, same dispatcher pattern, lazy `require` to keep `--help` fast.
39
+ - **Idempotency contract mirrors install.** Where install uses `created` / `updated` / `skipped-identical` / `skipped-not-found`, uninstall uses `removed` / `restored-from-bak` / `skipped-not-found`. Re-uninstalling a clean target returns all `skipped-not-found` and exit code 0.
40
+
41
+ ## File List
42
+
43
+ - `src/cli/HostInstaller.ts` — MODIFIED (added `HostUninstallResult` interface, `HostUninstallFileAction` type, `uninstall()` dispatcher, `uninstallForClaudeCode`, `uninstallForGeminiCli`, `uninstallForCodex`, private `removeFile`/`removeDir` helpers with `.bak` restore logic)
44
+ - `src/index.ts` — MODIFIED (added `system uninstall --host <host>` command using lazy `require('./cli/HostInstaller')`, JSON output, exit code on `HOST_NOT_YET_SUPPORTED`)
45
+ - `src/test_host_uninstaller.ts` — NEW (8 test scenarios, 67th test in suite)
46
+ - `package.json` — MODIFIED (added `test:host-uninstaller` script; appended to `test:all`)
47
+
48
+ ## Change Log
49
+
50
+ - 2026-05-11 — @dev (Charlie) — Implemented `HostInstaller.uninstall()` symmetric to `install()` from Story 3.3. Claude-code path removes prefix-scoped `openlife-*.md` agents (with `.bak` restore), the entire `commands/openlife/` namespace, and the staged MCP snippet — preserves user files, `.openlife/` state directory, and `~/.claude.json`. Added `openlife system uninstall --host <host>` CLI command following the lazy-require contract. `gemini-cli`/`codex` throw `HOST_NOT_YET_SUPPORTED` per 3.3 dispatcher pattern. test:all 66 → 67 verde. Status: Ready → InReview.
51
+
52
+ ## IDS check
53
+
54
+ **Decision:** ADAPT (extends the existing `HostInstaller` class with a symmetric reversal surface — no new file, no new dispatcher pattern). `HostUninstallResult` / `HostUninstallFileAction` shapes follow the install-side conventions (`HostInstallResult` / `HostInstallFileAction` in `src/cli/HostInstaller.ts:16-29`) — REUSE of structure. `HostNotYetSupportedError` is reused as-is from 3.3 for the unsupported hosts.
55
+
56
+ ## What unblocks for v1.1
57
+
58
+ - Story 3.5 (install wizard) — can offer "uninstall and switch host" as a flow now that uninstall is real
59
+ - Story 3.6 (docs per host) — claude-code uninstall path documents the exact reverse of install paths; `.bak` restore behavior is a documented feature
60
+ - Story 3.7 (gemini-cli + codex installers) — uninstall dispatcher slot is wired; each new host just needs `uninstallForX` alongside its `installForX`
61
+ - Story 3.8+ (`--purge` for full wipe including `.openlife/` state) — clear scope boundary now exists: 3.4 is "uninstall from host", purge is "wipe everything"
62
+
63
+ ## What this does NOT do
64
+
65
+ - Remove `.openlife/` runtime state directory → preserved by design; full wipe is a future `--purge` story
66
+ - Mutate `~/.claude.json` to remove MCP server entries → out of scope; 3.3 never wrote there, 3.4 cannot safely remove
67
+ - Ship `gemini-cli` or `codex` uninstall → throws `HOST_NOT_YET_SUPPORTED` by design; Story 3.7 wires both sides together
68
+ - Remove arbitrary files in `.claude/agents/` → strictly prefix-scoped to `openlife-*.md`; user files survive
69
+ - Implement an interactive wizard prompt for uninstall confirmation → Story 3.5 owns wizard UX
70
+ - Provide a manifest-based uninstall (read paths from an install-time manifest) → prefix + namespace contract is sufficient for the claude-code surface 3.3 ships
71
+ - Documentation updates beyond this story file → Story 3.6
@@ -0,0 +1,72 @@
1
+ # Story 3.5 — Interactive install wizard (`openlife init`)
2
+
3
+ **StoryId:** `3.5`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P1 (wizard is the primary UX surface for non-power-users adopting OpenLife)
7
+ **Cluster:** install-flow
8
+ **Depends on:** Story 3.1 (host enum + validator), Story 3.2 (dist-templates roster), Story 3.3 (host install dispatcher), Story 3.4 (reversible uninstall)
9
+
10
+ ## Description
11
+
12
+ Stories 3.1–3.4 wired the non-interactive automation surface: `openlife system setup --profile <p> --host <h>` and `openlife system uninstall --host <h>` produce real artifacts and reverse them. That path is correct for scripts and CI, but it presumes the operator already knows the flag matrix. New users do not. This story adds the conversational entry point.
13
+
14
+ `openlife init` is a new top-level command that walks the operator through profile, host, LLM model order, Telegram check (autonomous profile only), doctor toggle, and a confirm-preview before calling the same `InstallFlow.run()` Story 3.3 already exercises. The wizard is built on an `AnswerProvider` abstraction so tests inject canned answers instead of spawning a TTY. Re-entry is safe: when `<root>/.openlife/install-manifest.json` exists, the wizard offers `reinstall | repair | abort` before touching anything else. Defaults are pre-filled from `detectHostFromEnv()` and shown in brackets so the operator can blow through prompts with Enter when they do not care.
15
+
16
+ ## Acceptance Criteria
17
+
18
+ - [x] **New file** `src/cli/InstallWizard.ts` with class `InstallWizard`, `WizardResult` discriminated union, `AnswerProvider` interface, `ReadlineAnswerProvider` (Node built-in `readline`), `CannedAnswerProvider` (test seam, throws `WIZARD_TEST_OUT_OF_ANSWERS` when queue drains under dry-run)
19
+ - [x] **New CLI command** `openlife init` registered top-level in `src/index.ts` (not under `system`) using lazy `require('./cli/InstallWizard')` per the contract at `src/index.ts:11-13`
20
+ - [x] **Question flow:** existing-install detection → profile (default `framework`) → host (default from `detectHostFromEnv()`) → LLM model order (default chain from `ModelManager`) → Telegram token check (autonomous profile only) → skip-doctor? (default `no`) → confirm-preview
21
+ - [x] **Re-entry safety:** detects `<root>/.openlife/install-manifest.json` and offers `reinstall | repair | abort`; `abort` returns `{ ok: false, reason: 'user_aborted' }` before any other question is asked
22
+ - [x] **Bracketed defaults:** every prompt renders `Question? [default]:` so Enter accepts the default (universal CLI convention)
23
+ - [x] **Unsupported-host warning:** picking `gemini-cli` or `codex` is accepted but appends a warning to `WizardResult.warnings`; the downstream `InstallFlow.run()` already degrades gracefully via Story 3.3's `HostNotYetSupportedError` catch — wizard does not lie about availability
24
+ - [x] **Result shape:** success → `{ ok: true, options: InstallFlowOptions, preExistingAction?: 'reinstall' | 'repair', warnings?: string[] }`; failure → `{ ok: false, reason: 'user_aborted' | 'invalid_input', detail?: string }`
25
+ - [x] **No new runtime dependencies:** uses Node built-in `readline`; no `inquirer` / `prompts` / `enquirer` added to `package.json`
26
+ - [x] **Telegram check (autonomous only):** if `TELEGRAM_BOT_TOKEN` is unset, the wizard prints a non-blocking warning pointing at `.env` setup and continues
27
+ - [x] **Invalid input recovery:** the wizard re-prompts up to 3 times on parse failure, then returns `{ ok: false, reason: 'invalid_input', detail }` rather than throwing
28
+ - [x] **Regression test** `src/test_install_wizard.ts` covers 9 scenarios via `CannedAnswerProvider` (no TTY spawn): default-everything happy path, framework-profile path, autonomous-profile path with Telegram present, autonomous-profile path with Telegram missing (warning), unsupported-host warning for `gemini-cli`, re-entry detected → `reinstall`, re-entry detected → `repair`, re-entry detected → `abort` (returns `user_aborted`), out-of-answers throws `WIZARD_TEST_OUT_OF_ANSWERS`
29
+ - [x] Test wired into `test:all`; suite 67 → 68 verde
30
+
31
+ ## Dev Notes
32
+
33
+ - **Why an `AnswerProvider` abstraction?** Spawning a real TTY in tests is fragile — pseudo-TTYs differ across WSL / macOS / Linux, prompt timing races break `expect`-style scripts, and CI agents often have no TTY at all. The same `InstallWizard.run()` drives both `ReadlineAnswerProvider` (real users) and `CannedAnswerProvider` (queued answers in tests). Question logic stays decoupled from I/O — the wizard never imports `readline` directly outside the readline provider.
34
+ - **Why `openlife init` as a top-level command instead of `openlife system init`?** Discoverability. `init` is the universal "set me up" verb (`npm init`, `git init`, `gh repo init`, `cargo init`). Burying it under `system` would punish first-time users who don't know the subcommand tree yet. `openlife system setup --profile X --host Y` stays as the non-interactive automation path — both surfaces converge on the same `InstallFlow.run()`.
35
+ - **Why no new dependencies (e.g., `inquirer`, `prompts`)?** OpenLife's distribution must stay lean — every dep is one more lockfile entry, one more supply-chain surface, one more potential breaking-change in `npm install`. `readline` is built into Node since v0.x and covers everything this wizard needs (line input, history, prompts). The 200 LOC saved by `inquirer` is not worth the 30+ transitive deps it pulls.
36
+ - **Why allow unsupported hosts with a warning rather than block?** Story 3.3 already degrades gracefully — `InstallFlow.run()` catches `HostNotYetSupportedError` and reports a skipped host instead of aborting (`src/cli/InstallFlow.ts`). The wizard would be lying if it told users `gemini-cli` is "unavailable"; it's wired through the dispatcher, just no-op for now. Honest UX: "you can pick this, but the host wiring is deferred to Story 3.7 — `.openlife/` will still be set up". Warning + accept matches the rest of the install pipeline.
37
+ - **Why surface `preExistingAction` in `WizardResult`?** Downstream callers (printer in `src/index.ts`, future automation) may want to differentiate fresh-install messaging ("🚀 OpenLife installed") from re-entry ("🔧 OpenLife re-applied"). Without this field they would have to re-stat the manifest after the fact, racing against the install they just ran.
38
+ - **Why bracketed defaults `[claude-code]`?** Universal CLI convention from `apt`, `npm init`, `git rebase -i`. Lets the operator blow through five prompts with five Enters when they don't care. New users who read the bracket learn the default; power users who don't read it still pick the right thing.
39
+ - **Why a separate `WIZARD_TEST_OUT_OF_ANSWERS` error code?** Tests that drain the answer queue mid-flow indicate the wizard added a new prompt the test didn't account for — that's a regression signal, not a wizard bug. A stable error code makes the failure mode obvious in `test:install-wizard` output instead of surfacing as a generic `undefined` deref.
40
+ - **Why re-prompt 3× on invalid input instead of failing immediately?** Single-shot rejection on typos is hostile UX in an interactive wizard — the user is at the keyboard, they can fix it. Three attempts is the de facto convention (`sudo`, ssh, every login prompt). Beyond 3, returning `invalid_input` lets automation (or a frustrated user via Ctrl+C → `--auto-confirm` future flag) escape cleanly.
41
+
42
+ ## File List
43
+
44
+ - `src/cli/InstallWizard.ts` — NEW (class, `AnswerProvider` interface, `ReadlineAnswerProvider`, `CannedAnswerProvider`, `WizardResult` union, `WIZARD_TEST_OUT_OF_ANSWERS` constant, question-flow orchestration)
45
+ - `src/index.ts` — MODIFIED (added top-level `init` command using lazy `require('./cli/InstallWizard')`, prints `JSON.stringify(result, null, 2)`, sets `process.exitCode = 1` on `{ ok: false }`)
46
+ - `src/test_install_wizard.ts` — NEW (9 test scenarios via `CannedAnswerProvider`, 68th test in suite)
47
+ - `package.json` — MODIFIED (added `test:install-wizard` script; appended to `test:all`)
48
+
49
+ ## Change Log
50
+
51
+ - 2026-05-11 — @dev (Charlie) — Implemented `InstallWizard` with `AnswerProvider` abstraction (`ReadlineAnswerProvider` for TTY users, `CannedAnswerProvider` for tests). New top-level `openlife init` command walks operator through profile → host → model order → Telegram check → doctor toggle → confirm, with re-entry detection via `<root>/.openlife/install-manifest.json` (offers `reinstall | repair | abort`). Unsupported hosts (`gemini-cli`, `codex`) accepted with warning per Story 3.3 graceful-degradation contract. Zero new runtime dependencies. test:all 67 → 68 verde. Status: Ready → InReview.
52
+
53
+ ## IDS check
54
+
55
+ **Decision:** CREATE (new wizard surface — no prior interactive entry point exists in OpenLife) + ADAPT (`src/index.ts` extended with one top-level command following the lazy-require pattern from 3.3/3.4). `WizardResult` discriminated-union shape REUSEs the `{ ok: true, ... } | { ok: false, reason, detail? }` envelope already established by CLI command handlers (`src/index.ts:58-66`). `AnswerProvider` interface is a new abstraction, justified by test-seam requirements no existing class addresses.
56
+
57
+ ## What unblocks for v1.1
58
+
59
+ - Story 3.6 (docs per host) — wizard screenshots/transcripts become the "Getting Started" anchor; documentation can recommend `openlife init` as the single onboarding entry point
60
+ - Story 3.7 (gemini-cli + codex installers) — wizard already accepts these hosts with a warning; landing the installers just flips the warning to a no-op without any wizard change
61
+ - Story 3.8+ (`--auto-confirm` / non-interactive wizard) — `AnswerProvider` abstraction makes this a one-class addition (e.g., `EnvAnswerProvider` reading `OPENLIFE_INIT_*` env vars), no rework of the flow
62
+ - Story 3.9+ (uninstall wizard) — `InstallWizard` flow shape is the template; mirror it with `UninstallWizard` calling `HostInstaller.uninstall()` from Story 3.4
63
+
64
+ ## What this does NOT do
65
+
66
+ - Implement `bin/openlife-mcp.js` (the MCP server itself) → still deferred from 3.3; wizard surfaces a "MCP server pending" note but does not run one
67
+ - Auto-merge the staged MCP snippet into `~/.claude.json` → out of scope; same security/UX trap rationale as 3.3 — operator merges manually after wizard exits
68
+ - Provide a non-interactive scriptable wizard (`--auto-confirm` / `--answers-file` style) → future enhancement; `AnswerProvider` abstraction is the seam, but no env-driven provider ships in 3.5
69
+ - Localize the prompts beyond the few Portuguese strings already present in the codebase → English-default; PT-BR pass is a separate v1.1 docs/localization story
70
+ - Ship an uninstall wizard → 3.4 exposes the CLI command; an interactive uninstall flow is deferred to a follow-up story
71
+ - Add a new runtime dependency (`inquirer` / `prompts` / etc.) → built on Node's `readline` by design
72
+ - Documentation updates beyond this story file → Story 3.6
@@ -0,0 +1,69 @@
1
+ # Story 3.6 — Per-host install documentation + doc-parity regression test
2
+
3
+ **StoryId:** `3.6`
4
+ **Epic:** `epic-multi-host-installer` (v1.1)
5
+ **Status:** InReview
6
+ **Severity:** P2 (documentation surface, not runtime — but blocks v1.1 onboarding without it)
7
+ **Cluster:** install-flow
8
+ **Depends on:** Story 3.1 (host enum), Story 3.2 (dist-templates roster), Story 3.3 (host install dispatcher), Story 3.4 (reversible uninstall), Story 3.5 (`openlife init` wizard)
9
+
10
+ ## Description
11
+
12
+ Stories 3.1–3.5 expanded the installer surface — three host slots, a wizard, reversible uninstall — but the public docs still read as if `openlife system setup` is the only entry point and `claude-code` is the only host that exists. A new user landing on the README today gets a Quick Start that does not match what `openlife --help` advertises, and there is nothing pointing at the per-host nuances (`HOST_NOT_YET_SUPPORTED` for `gemini-cli`/`codex`, manual `~/.claude.json` merge step, `.openlife/install-manifest.json` lifecycle). Story 3.6 closes that gap and adds the regression test that prevents it from re-opening.
13
+
14
+ `INSTALL.md` is expanded into a full install handbook: quick start anchored on `openlife init`, a host coverage matrix, the two profiles (`framework` / `autonomous`), non-interactive scripted install via `system setup`, uninstall flow from Story 3.4, and a troubleshooting appendix for the failure modes the wizard and dispatcher actually emit. `README.md` Quick Start is rewritten to recommend `openlife init` first and link to `INSTALL.md` for everything else. Three per-host references land under `docs/install/`: `claude-code.md` is the real reference for the supported path, `gemini-cli.md` and `codex.md` document the `HOST_NOT_YET_SUPPORTED` reserved state — the operator can still pick them in the wizard and `.openlife/` will be created via graceful degradation, but no host-side artifacts ship until Story 3.7. The whole surface is then locked by `src/test_multi_host_docs_parity.ts`, 8 asserts that fail loudly the next time docs drift.
15
+
16
+ ## Acceptance Criteria
17
+
18
+ - [x] **INSTALL.md** expanded with: (a) `openlife init` quick start, (b) host coverage matrix (`claude-code` supported, `gemini-cli`/`codex` reserved), (c) `framework` vs `autonomous` profile table, (d) non-interactive `system setup --profile <p> --host <h>` recipe, (e) `system uninstall --host <host>` flow per Story 3.4, (f) troubleshooting section covering `HOST_NOT_YET_SUPPORTED`, missing `TELEGRAM_BOT_TOKEN`, manual `~/.claude.json` MCP merge, `.openlife/install-manifest.json` re-entry
19
+ - [x] **README.md** Quick Start updated: recommends `openlife init` as the primary onboarding entry point, includes a 3-row host table, links to `INSTALL.md` and to `docs/install/<host>.md`
20
+ - [x] **`docs/install/claude-code.md`** — real reference: agent prefix contract (`openlife-*.md`), `commands/openlife/` namespace, MCP snippet at `<root>/.openlife/install-mcp-snippet.json` (NOT auto-merged), `.bak` restore behavior on uninstall, idempotency contract from 3.3/3.4
21
+ - [x] **`docs/install/gemini-cli.md`** — documents reserved `HOST_NOT_YET_SUPPORTED` state, explains that the wizard accepts it (`.openlife/` still created via 3.3 graceful-degradation catch), points at Story 3.7 as the unblocking work
22
+ - [x] **`docs/install/codex.md`** — same `HOST_NOT_YET_SUPPORTED` template as gemini-cli; documents the dispatcher contract from 3.3
23
+ - [x] **Regression test** `src/test_multi_host_docs_parity.ts` with 8 asserts: (1) INSTALL.md mentions `openlife init`, (2) INSTALL.md lists all three hosts by ID, (3) INSTALL.md mentions both profiles `framework` and `autonomous`, (4) INSTALL.md mentions `system uninstall`, (5) README.md Quick Start mentions `openlife init`, (6) `docs/install/claude-code.md` mentions `.openlife/install-mcp-snippet.json` (the manual-merge contract), (7) `docs/install/gemini-cli.md` mentions `HOST_NOT_YET_SUPPORTED`, (8) `docs/install/codex.md` mentions `HOST_NOT_YET_SUPPORTED`
24
+ - [x] Test wired into `test:all` via `test:multi-host-docs-parity`; suite 68 → 69 verde
25
+
26
+ ## Dev Notes
27
+
28
+ - **Why a doc-parity regression test instead of trusting reviewers?** OpenLife's own audit on 2026-05-11 flagged 124 doc-vs-code parity gaps accumulated since v1.0. Reviewers consistently catch code drift; they consistently miss doc drift because the diff for "code changed, docs unchanged" looks fine in isolation. A deterministic test that greps the doc files for stable anchors (`openlife init`, host IDs, `HOST_NOT_YET_SUPPORTED`) flips that failure mode into a red `npm run test:all`. Cheap, blunt, effective.
29
+ - **Why INSTALL.md in English when the codebase is mixed PT-BR/EN?** Convention of the existing file: `INSTALL.md` is already English, and the public docs surface (`README.md`, `docs/install/*`) is what external adopters read first. Inline comments in `src/` stay mixed (operator-facing console output uses Portuguese strings in some places per `src/index.ts:247`), but public docs converge on English until a deliberate localization pass lands. PT-BR localization is explicitly out of scope here.
30
+ - **Why ship stub docs for `gemini-cli` / `codex` instead of removing them from the wizard menu?** Story 3.5 deliberately accepts these hosts with a warning because Story 3.3's dispatcher degrades gracefully — the operator CAN pick them today, `.openlife/` still gets created. Hiding the option in docs while the wizard accepts it would be the worst kind of doc drift: the user sees the prompt, picks `gemini-cli`, gets a "skipped, host not yet supported" result, and has no doc to ground that message. Honest documentation matches the wizard surface; the stubs are short on purpose, but they exist.
31
+ - **Why call out the `~/.claude.json` manual-merge step so loudly?** This is the #1 failure-mode trap from Story 3.3 — the MCP snippet is staged at `<root>/.openlife/install-mcp-snippet.json` and never auto-merged into the user's global Claude config (security/UX rationale from 3.3 stands). Without a doc note, the user runs `openlife init`, sees the success message, opens Claude Code, and wonders why no OpenLife MCP tools appear. A two-sentence call-out in `INSTALL.md` and `docs/install/claude-code.md` saves a support round-trip and prevents a "the installer is broken" issue that is actually a "the docs did not warn you" issue.
32
+ - **Why split `docs/install/<host>.md` out of `INSTALL.md` instead of one big file?** Reading-curve separation. `INSTALL.md` is the overview a casual adopter reads end-to-end (quick start + matrix + troubleshooting). `docs/install/<host>.md` is the reference a power user dives into for the specific host they care about (`claude-code` for now). Mixing them forces the casual reader to skim past gemini-cli/codex reserved-state notes they do not need, and forces the power user to grep through quick-start narrative they already know. Same split convention as `npm` (`README` overview + `docs/cli-commands/<verb>.md` per command).
33
+ - **Why are the doc-parity asserts greps and not Markdown-AST parsing?** A grep for stable anchor strings (`openlife init`, `HOST_NOT_YET_SUPPORTED`, `system uninstall`) is brittle in the right direction — if a future PR rewrites the docs without preserving the contract, the test fails. AST parsing would let rephrasing pass silently. The goal is to catch silent removal, not enforce specific phrasing. Eight asserts is the minimum that covers the surface 3.1–3.5 expanded; more asserts = more false positives on benign rewordings.
34
+ - **Why is this Severity P2 instead of P1?** No runtime code path is broken without these docs — `openlife init`, `system setup`, and `system uninstall` all work today (3.3/3.4/3.5). But v1.1 cannot ship with a Quick Start that does not mention the new primary entry point. P2 = "blocks the release, does not block a running production install".
35
+
36
+ ## File List
37
+
38
+ - `INSTALL.md` — MODIFIED (quick start anchored on `openlife init`, host matrix, profile table, non-interactive recipe, uninstall flow, troubleshooting appendix)
39
+ - `README.md` — MODIFIED (Quick Start rewritten to lead with `openlife init`, 3-row host table, links to INSTALL.md and `docs/install/<host>.md`)
40
+ - `docs/install/claude-code.md` — NEW (per-host reference: prefix contract, namespace, MCP snippet manual-merge, `.bak` restore, idempotency)
41
+ - `docs/install/gemini-cli.md` — NEW (reserved `HOST_NOT_YET_SUPPORTED` doc; points at Story 3.7)
42
+ - `docs/install/codex.md` — NEW (reserved `HOST_NOT_YET_SUPPORTED` doc; points at Story 3.7)
43
+ - `src/test_multi_host_docs_parity.ts` — NEW (8 grep-based asserts, 69th test in suite)
44
+ - `package.json` — MODIFIED (added `test:multi-host-docs-parity` script; appended to `test:all`)
45
+
46
+ ## Change Log
47
+
48
+ - 2026-05-11 — @dev (Charlie) — Documented the installer surface expanded by 3.1–3.5. Rewrote `INSTALL.md` and `README.md` Quick Start around `openlife init`. Added `docs/install/{claude-code,gemini-cli,codex}.md` — claude-code as real reference, other two as `HOST_NOT_YET_SUPPORTED` stubs aligned with Story 3.5's accept-with-warning contract. Added `src/test_multi_host_docs_parity.ts` (8 asserts) to lock doc anchors against drift. test:all 68 → 69 verde. Status: Ready → InReview.
49
+
50
+ ## IDS check
51
+
52
+ **Decision:** CREATE (three new per-host doc files + one new regression test — no prior per-host doc structure exists) + ADAPT (`INSTALL.md`, `README.md`, `package.json` extended with the same patterns already established). Doc-parity test pattern REUSEs the grep-based assert style from existing `test_*` files (e.g., `test_openlife_runtime_source_truth.ts`'s string-presence asserts). No new framework, no new test harness — same standalone `test_*.ts` convention.
53
+
54
+ ## What unblocks for v1.1
55
+
56
+ - v1.1 public release — Quick Start now matches the surface `openlife --help` advertises; adopters can complete onboarding without reading source
57
+ - Story 3.7 (gemini-cli + codex installers) — when those hosts land, the existing stub docs flip from "reserved" to "supported" with a focused edit, parity test anchors stay stable
58
+ - Story 3.8+ (localization pass) — English baseline is now consistent across `INSTALL.md`, `README.md`, and `docs/install/*`; a PT-BR mirror has one canonical source to translate from
59
+ - Future doc audits — the doc-parity test pattern can be extended (more asserts, more anchor files) as new install features land, without inventing new test infrastructure
60
+
61
+ ## What this does NOT do
62
+
63
+ - Localize docs into PT-BR → English baseline only; deferred to a dedicated localization story
64
+ - Add screenshots, GIFs, or asciinema casts of the wizard → text-only docs in this pass; visual assets are a separate polish story
65
+ - Document DEPS troubleshooting (Node version mismatches, `ffmpeg` missing, Ollama unreachable) → scope is install/uninstall flow only; runtime-deps troubleshooting belongs in a `DEPS.md` story
66
+ - Document the autonomous-profile Telegram bot integration end-to-end (token provisioning, `OPENLIFE_TELEGRAM_ALLOWED_USER_ID`, webhook setup) → INSTALL.md mentions the env var as a warning anchor; full Telegram onboarding is a separate doc story
67
+ - Auto-merge `~/.claude.json` MCP entries → still out of scope per 3.3/3.4; docs only describe the manual merge
68
+ - Ship `gemini-cli` or `codex` installers → Story 3.7
69
+ - Add an interactive uninstall wizard doc → CLI-only documented; wizard surface is `openlife init`, uninstall stays scriptable for now