@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.
- package/INSTALL.md +266 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/bin/openlife.js +3 -0
- package/dist/admin_panel_server.js +66 -0
- package/dist/cli/AgentManager.js +109 -0
- package/dist/cli/AutonomousInstaller.js +134 -0
- package/dist/cli/DreamOrganizer.js +88 -0
- package/dist/cli/HostInstaller.js +426 -0
- package/dist/cli/InstallBanner.js +16 -0
- package/dist/cli/InstallFlow.js +256 -0
- package/dist/cli/InstallHeadless.js +47 -0
- package/dist/cli/InstallModules.js +148 -0
- package/dist/cli/InstallStateStore.js +75 -0
- package/dist/cli/InstallWizard.js +364 -0
- package/dist/cli/ProfileManager.js +163 -0
- package/dist/cli/SystemInstaller.js +89 -0
- package/dist/cli/WorldClassCommands.js +208 -0
- package/dist/design/DesignMdImporter.js +82 -0
- package/dist/design/DesignMdMode.js +93 -0
- package/dist/design/DesignMdRegistry.js +67 -0
- package/dist/index.js +2575 -0
- package/dist/memory/ConversationMemory.js +33 -0
- package/dist/memory/LocalMemoryProvider.js +86 -0
- package/dist/memory/Mem0Provider.js +16 -0
- package/dist/memory/MemoryNamespacePolicy.js +27 -0
- package/dist/memory/MemoryOrchestrator.js +65 -0
- package/dist/memory/MemoryPromotionFlow.js +32 -0
- package/dist/memory/MemoryProvider.js +2 -0
- package/dist/memory/MemoryProviderRegistry.js +27 -0
- package/dist/memory/MemoryRetentionPolicy.js +60 -0
- package/dist/memory/MempalaceProvider.js +72 -0
- package/dist/memory/OmniMemory.js +106 -0
- package/dist/memory/RedisAgentMemoryProvider.js +16 -0
- package/dist/memory/SessionManager.js +86 -0
- package/dist/memory/ZepGraphitiProvider.js +16 -0
- package/dist/orchestrator/AgentRegistry.js +56 -0
- package/dist/orchestrator/AgentScoring.js +82 -0
- package/dist/orchestrator/AgentTeam.js +22 -0
- package/dist/orchestrator/ArbitrationAgent.js +43 -0
- package/dist/orchestrator/ArbitrationScorecard.js +17 -0
- package/dist/orchestrator/AssetPromotionEngine.js +65 -0
- package/dist/orchestrator/AssetReuseRouter.js +63 -0
- package/dist/orchestrator/BenchmarkEngine.js +75 -0
- package/dist/orchestrator/Brain.js +298 -0
- package/dist/orchestrator/CadenceEngine.js +76 -0
- package/dist/orchestrator/CapabilityRouter.js +36 -0
- package/dist/orchestrator/CommandLanguage.js +27 -0
- package/dist/orchestrator/CommandRouter.js +70 -0
- package/dist/orchestrator/ConsequenceForecaster.js +286 -0
- package/dist/orchestrator/CronManager.js +286 -0
- package/dist/orchestrator/DynamicAgentBuilder.js +48 -0
- package/dist/orchestrator/DynamicAgentExecutor.js +15 -0
- package/dist/orchestrator/EnterpriseAgenticCore.js +276 -0
- package/dist/orchestrator/ExecutionBoard.js +86 -0
- package/dist/orchestrator/ExecutionIntent.js +13 -0
- package/dist/orchestrator/ExecutionModePolicy.js +48 -0
- package/dist/orchestrator/ExecutionRouter.js +9 -0
- package/dist/orchestrator/ExecutionState.js +20 -0
- package/dist/orchestrator/ExecutorHealth.js +86 -0
- package/dist/orchestrator/ExternalCatalogRegistry.js +83 -0
- package/dist/orchestrator/Gatekeeper.js +414 -0
- package/dist/orchestrator/Gateway.js +508 -0
- package/dist/orchestrator/GovernanceConsentStore.js +66 -0
- package/dist/orchestrator/GovernanceLayer.js +179 -0
- package/dist/orchestrator/GovernancePolicyStore.js +53 -0
- package/dist/orchestrator/GovernanceScopeLedger.js +134 -0
- package/dist/orchestrator/GovernanceScopePolicy.js +67 -0
- package/dist/orchestrator/IntentClassifier.js +45 -0
- package/dist/orchestrator/JobLifecycle.js +91 -0
- package/dist/orchestrator/LearningRouter.js +24 -0
- package/dist/orchestrator/MediaManager.js +92 -0
- package/dist/orchestrator/MemoryCuratorAgent.js +41 -0
- package/dist/orchestrator/MissionState.js +155 -0
- package/dist/orchestrator/ModelManager.js +84 -0
- package/dist/orchestrator/OperatingSystem.js +71 -0
- package/dist/orchestrator/OperationalMemoryStore.js +94 -0
- package/dist/orchestrator/OptimizationLoop.js +72 -0
- package/dist/orchestrator/OrchestrationLoop.js +905 -0
- package/dist/orchestrator/OrgStructure.js +88 -0
- package/dist/orchestrator/OutcomeSimulator.js +46 -0
- package/dist/orchestrator/ParallelOrchestrationLoop.js +36 -0
- package/dist/orchestrator/PerformanceScorecard.js +105 -0
- package/dist/orchestrator/PlannerAgent.js +46 -0
- package/dist/orchestrator/ProcessSandbox.js +129 -0
- package/dist/orchestrator/PromotionPipeline.js +74 -0
- package/dist/orchestrator/PromotionReviewGate.js +11 -0
- package/dist/orchestrator/QueueScheduler.js +260 -0
- package/dist/orchestrator/ReleaseGate.js +36 -0
- package/dist/orchestrator/ReleaseWorkflow.js +68 -0
- package/dist/orchestrator/RemotePublisher.js +139 -0
- package/dist/orchestrator/ReuseEngine.js +89 -0
- package/dist/orchestrator/ReviewerAgent.js +49 -0
- package/dist/orchestrator/RoleHandoff.js +65 -0
- package/dist/orchestrator/RuntimeHealthMonitor.js +143 -0
- package/dist/orchestrator/RuntimePolicy.js +105 -0
- package/dist/orchestrator/RuntimeProbe.js +97 -0
- package/dist/orchestrator/RuntimeRegistry.js +73 -0
- package/dist/orchestrator/SandboxPolicy.js +22 -0
- package/dist/orchestrator/SecurityDownloadGuard.js +169 -0
- package/dist/orchestrator/SecurityEventStore.js +58 -0
- package/dist/orchestrator/ServiceCompletionPolicy.js +36 -0
- package/dist/orchestrator/ServiceState.js +195 -0
- package/dist/orchestrator/SkillCreator.js +404 -0
- package/dist/orchestrator/SkillLearningLoop.js +57 -0
- package/dist/orchestrator/SkillManager.js +75 -0
- package/dist/orchestrator/SkillNetwork.js +29 -0
- package/dist/orchestrator/SkillRegistryV2.js +28 -0
- package/dist/orchestrator/SkillScoring.js +70 -0
- package/dist/orchestrator/SquadAutoCreator.js +64 -0
- package/dist/orchestrator/SquadCreator.js +727 -0
- package/dist/orchestrator/SquadRegistry.js +28 -0
- package/dist/orchestrator/SquadRouter.js +33 -0
- package/dist/orchestrator/SquadScoring.js +70 -0
- package/dist/orchestrator/SubagentLifecycle.js +90 -0
- package/dist/orchestrator/SynthesizerAgent.js +48 -0
- package/dist/orchestrator/SystemDoctor.js +224 -0
- package/dist/orchestrator/TaskExecutor.js +422 -0
- package/dist/orchestrator/TeammateBoard.js +61 -0
- package/dist/orchestrator/TestHarness.js +184 -0
- package/dist/orchestrator/VoiceManager.js +203 -0
- package/dist/orchestrator/VoiceRouter.js +89 -0
- package/dist/orchestrator/capability/CapabilityGenesisEngine.js +278 -0
- package/dist/orchestrator/capability/CapabilityPackParser.js +223 -0
- package/dist/orchestrator/capability/CapabilityPackSchema.js +62 -0
- package/dist/orchestrator/capability/CapabilityPackState.js +163 -0
- package/dist/orchestrator/providers/AgentProvider.js +2 -0
- package/dist/orchestrator/providers/CapabilityProvider.js +12 -0
- package/dist/orchestrator/providers/CloudAgentProvider.js +55 -0
- package/dist/orchestrator/providers/CloudSkillProvider.js +55 -0
- package/dist/orchestrator/providers/CloudSquadProvider.js +55 -0
- package/dist/orchestrator/providers/CompositeAgentProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeCapabilityProvider.js +25 -0
- package/dist/orchestrator/providers/CompositeSkillProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeSquadProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeWorkflowProvider.js +46 -0
- package/dist/orchestrator/providers/FileAgentProvider.js +105 -0
- package/dist/orchestrator/providers/FileCapabilityProvider.js +106 -0
- package/dist/orchestrator/providers/FileSkillProvider.js +65 -0
- package/dist/orchestrator/providers/FileSquadProvider.js +69 -0
- package/dist/orchestrator/providers/FileWorkflowProvider.js +103 -0
- package/dist/orchestrator/providers/SkillProvider.js +2 -0
- package/dist/orchestrator/providers/SquadProvider.js +2 -0
- package/dist/orchestrator/toolset/ToolsetGuard.js +69 -0
- package/dist/orchestrator/toolset/ToolsetRegistry.js +65 -0
- package/dist/orchestrator/toolset/ToolsetSchema.js +21 -0
- package/dist/orchestrator/util/AtomicWriter.js +204 -0
- package/dist/orchestrator/util/DistributedLock.js +232 -0
- package/dist/orchestrator/util/TemplateRenderer.js +87 -0
- package/dist/orchestrator/util/WatchdogHeartbeat.js +116 -0
- package/dist/orchestrator/workflow/ConditionParser.js +232 -0
- package/dist/orchestrator/workflow/WorkflowEngine.js +379 -0
- package/dist/orchestrator/workflow/WorkflowParser.js +368 -0
- package/dist/orchestrator/workflow/WorkflowSchema.js +65 -0
- package/dist/orchestrator/workflow/WorkflowState.js +11 -0
- package/dist/reversa/ReversaAgent.js +134 -0
- package/dist/reversa/ReversaContracts.js +62 -0
- package/dist/reversa/ReversaExecutors.js +65 -0
- package/dist/skills/SkillRegistry.js +71 -0
- package/dist/squads/SquadManager.js +87 -0
- package/dist/test_admin_teams_networks.js +54 -0
- package/dist/test_agent_team_skill_network.js +15 -0
- package/dist/test_aiobuilder_cli_parity.js +169 -0
- package/dist/test_ask_exit.js +73 -0
- package/dist/test_atomic_writer.js +209 -0
- package/dist/test_autonomous_soak.js +141 -0
- package/dist/test_benchmark_engine.js +41 -0
- package/dist/test_brain_error_diagnostics.js +51 -0
- package/dist/test_brain_fallback_chain.js +93 -0
- package/dist/test_capability_genesis_engine.js +225 -0
- package/dist/test_capability_pack_schema.js +214 -0
- package/dist/test_catalog_quality.js +150 -0
- package/dist/test_cli_crud_roundtrip.js +154 -0
- package/dist/test_cli_diagnostics.js +131 -0
- package/dist/test_cli_doc_parity.js +126 -0
- package/dist/test_cli_help_surface.js +106 -0
- package/dist/test_cli_service_commands.js +83 -0
- package/dist/test_consequence_forecast_brain.js +165 -0
- package/dist/test_consequence_forecaster.js +24 -0
- package/dist/test_conversation_memory.js +36 -0
- package/dist/test_create_entities.js +54 -0
- package/dist/test_creator_placeholders_completed.js +177 -0
- package/dist/test_cron_manager.js +123 -0
- package/dist/test_daemon_sigterm.js +72 -0
- package/dist/test_deep_research_capability.js +87 -0
- package/dist/test_designmd_import_registry.js +16 -0
- package/dist/test_designmd_mode.js +50 -0
- package/dist/test_designmd_mode_workspace.js +13 -0
- package/dist/test_dist_templates_layout.js +135 -0
- package/dist/test_distributed_lock.js +201 -0
- package/dist/test_distribution_installability.js +67 -0
- package/dist/test_doctor_sandbox_check.js +44 -0
- package/dist/test_dream_organizer.js +25 -0
- package/dist/test_dual_mode.js +15 -0
- package/dist/test_enterprise_agentic_core.js +128 -0
- package/dist/test_forecast_brain_wiring.js +87 -0
- package/dist/test_gateway_telegram_guardrails.js +52 -0
- package/dist/test_governance.js +34 -0
- package/dist/test_governance_advanced.js +75 -0
- package/dist/test_governance_scope_ledger.js +147 -0
- package/dist/test_governance_v13_policies.js +44 -0
- package/dist/test_guided_creator_cli.js +100 -0
- package/dist/test_host_install_e2e.js +324 -0
- package/dist/test_host_installer.js +259 -0
- package/dist/test_host_installers_gemini_codex.js +95 -0
- package/dist/test_host_uninstaller.js +295 -0
- package/dist/test_install_flow.js +70 -0
- package/dist/test_install_flow_host_validation.js +143 -0
- package/dist/test_install_wizard.js +272 -0
- package/dist/test_integration_gemini_live.js +95 -0
- package/dist/test_integration_http_trigger_live.js +154 -0
- package/dist/test_integration_telegram_live.js +102 -0
- package/dist/test_job_lifecycle.js +16 -0
- package/dist/test_memory_orchestrator.js +33 -0
- package/dist/test_memory_promotion.js +36 -0
- package/dist/test_memory_retention.js +37 -0
- package/dist/test_mission_checkpoint.js +204 -0
- package/dist/test_multi_host_docs_parity.js +125 -0
- package/dist/test_openlife_auto_creator_routing.js +69 -0
- package/dist/test_openlife_evolution_surface.js +77 -0
- package/dist/test_openlife_gatekeeper_routing.js +15 -0
- package/dist/test_openlife_routing_surface.js +27 -0
- package/dist/test_openlife_runtime_source_truth.js +25 -0
- package/dist/test_operating_system.js +45 -0
- package/dist/test_optimization_loop.js +38 -0
- package/dist/test_orchestration_assets_lifecycle.js +78 -0
- package/dist/test_outcome_simulator.js +38 -0
- package/dist/test_performance_latency.js +215 -0
- package/dist/test_performance_scorecard.js +38 -0
- package/dist/test_phase1_check_exit.js +103 -0
- package/dist/test_phase6_board.js +31 -0
- package/dist/test_phase6_cadence.js +29 -0
- package/dist/test_phase6_ops.js +37 -0
- package/dist/test_post_mission_evaluation.js +190 -0
- package/dist/test_process_sandbox.js +88 -0
- package/dist/test_profile_toolset_mcp.js +125 -0
- package/dist/test_queue_scheduler.js +239 -0
- package/dist/test_release_gate.js +23 -0
- package/dist/test_remote_publish.js +193 -0
- package/dist/test_reversa_contracts_e2e.js +48 -0
- package/dist/test_reversa_export_and_strict.js +51 -0
- package/dist/test_reversa_full_execution.js +12 -0
- package/dist/test_reversa_lite.js +9 -0
- package/dist/test_royal_stack_golden.js +179 -0
- package/dist/test_runtime_health_backoff.js +154 -0
- package/dist/test_runtime_policy.js +26 -0
- package/dist/test_runtime_probe.js +19 -0
- package/dist/test_runtime_profile_oauth_only.js +262 -0
- package/dist/test_runtime_registry.js +11 -0
- package/dist/test_security_download_and_scan.js +103 -0
- package/dist/test_security_download_guard.js +14 -0
- package/dist/test_service_command_surface.js +12 -0
- package/dist/test_service_completion_policy.js +32 -0
- package/dist/test_service_guardrails_delete.js +12 -0
- package/dist/test_service_mode_explicit_only.js +174 -0
- package/dist/test_sources_import_ref.js +46 -0
- package/dist/test_sources_scaffold.js +43 -0
- package/dist/test_squad_skill_creator.js +305 -0
- package/dist/test_squad_skill_design_llm.js +176 -0
- package/dist/test_subsystems_org_state.js +271 -0
- package/dist/test_subsystems_promotion_memory_assets.js +343 -0
- package/dist/test_subsystems_routing_governance.js +234 -0
- package/dist/test_task_executor_sandbox_optin.js +127 -0
- package/dist/test_teammate_learning.js +15 -0
- package/dist/test_telegram_delete_guardrail.js +21 -0
- package/dist/test_toolset_enforcement.js +188 -0
- package/dist/test_trigger_basic_auth.js +112 -0
- package/dist/test_util/doc_parity.js +120 -0
- package/dist/test_v15_e2e_integration.js +207 -0
- package/dist/test_watchdog_heartbeat.js +152 -0
- package/dist/test_workflow_condition_parser.js +63 -0
- package/dist/test_workflow_e2e.js +240 -0
- package/dist/test_workflow_engine.js +330 -0
- package/dist/test_workflow_parser.js +245 -0
- package/dist/test_workflow_schema_backward_compat.js +197 -0
- package/dist-templates/README.md +91 -0
- package/dist-templates/claude-code/agents/openlife-atlas.md +52 -0
- package/dist-templates/claude-code/agents/openlife-forge.md +42 -0
- package/dist-templates/claude-code/agents/openlife-genesis.md +59 -0
- package/dist-templates/claude-code/agents/openlife-lyra.md +40 -0
- package/dist-templates/claude-code/agents/openlife-maestro.md +45 -0
- package/dist-templates/claude-code/commands/openlife/ask.md +14 -0
- package/dist-templates/claude-code/commands/openlife/doctor.md +19 -0
- package/dist-templates/claude-code/commands/openlife/dream.md +20 -0
- package/dist-templates/claude-code/commands/openlife/status.md +14 -0
- package/dist-templates/claude-code/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/codex/README.md +7 -0
- package/dist-templates/codex/agents/openlife-atlas.md +52 -0
- package/dist-templates/codex/agents/openlife-forge.md +42 -0
- package/dist-templates/codex/agents/openlife-genesis.md +59 -0
- package/dist-templates/codex/agents/openlife-lyra.md +40 -0
- package/dist-templates/codex/agents/openlife-maestro.md +45 -0
- package/dist-templates/codex/commands/openlife/ask.md +14 -0
- package/dist-templates/codex/commands/openlife/doctor.md +19 -0
- package/dist-templates/codex/commands/openlife/dream.md +20 -0
- package/dist-templates/codex/commands/openlife/status.md +14 -0
- package/dist-templates/codex/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/gemini-cli/README.md +8 -0
- package/dist-templates/gemini-cli/agents/openlife-atlas.md +52 -0
- package/dist-templates/gemini-cli/agents/openlife-forge.md +42 -0
- package/dist-templates/gemini-cli/agents/openlife-genesis.md +59 -0
- package/dist-templates/gemini-cli/agents/openlife-lyra.md +40 -0
- package/dist-templates/gemini-cli/agents/openlife-maestro.md +45 -0
- package/dist-templates/gemini-cli/commands/openlife/ask.md +14 -0
- package/dist-templates/gemini-cli/commands/openlife/doctor.md +19 -0
- package/dist-templates/gemini-cli/commands/openlife/dream.md +20 -0
- package/dist-templates/gemini-cli/commands/openlife/status.md +14 -0
- package/dist-templates/gemini-cli/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/skill-template/README.md +34 -0
- package/dist-templates/skill-template/SKILL.md.template +59 -0
- package/dist-templates/squad-template/README.md +82 -0
- package/dist-templates/squad-template/SQUAD.md.template +51 -0
- package/dist-templates/squad-template/agent-template.md +51 -0
- package/dist-templates/squad-template/checklist-template.md +25 -0
- package/dist-templates/squad-template/task-template.md +36 -0
- package/dist-templates/workflows/PORTED_WORKFLOWS.md +60 -0
- package/dist-templates/workflows/brownfield-discovery.yaml +137 -0
- package/dist-templates/workflows/greenfield-fullstack.yaml +132 -0
- package/dist-templates/workflows/qa-loop.yaml +125 -0
- package/dist-templates/workflows/story-development-cycle.yaml +80 -0
- package/docs/CHANGELOG_FEATURE_ROLLOUT_DESIGNMD.md +43 -0
- package/docs/EXTERNAL_SOURCES_AND_SECURITY_GUARD.md +33 -0
- package/docs/OPENLIFE_AUDIT_2026-05-06.md +170 -0
- package/docs/OPENLIFE_CONSOLIDATED_PLAN_2026-05-06.md +299 -0
- package/docs/OPENLIFE_DUAL_MODE_IMPLEMENTATION_PLAN.md +205 -0
- package/docs/OPENLIFE_EVOLUTION_SURFACE_2026-05-07.md +53 -0
- package/docs/OPENLIFE_SKILLS_IMPORT_2026-05-07.json +223 -0
- package/docs/OPENLIFE_SQUADS_IMPORT_2026-05-07.json +184 -0
- package/docs/PAPERCLIP_OPENLIFE_INVESTIGATION.md +85 -0
- package/docs/README.md +28 -0
- package/docs/RELEASE_ORGANIZATION_PLAN.md +164 -0
- package/docs/audit/CLI-EXECUTION-RESULTS.md +113 -0
- package/docs/audit/CLI-MATRIX.md +556 -0
- package/docs/audit/DOC-PARITY-GAPS.md +351 -0
- package/docs/audit/ORCHESTRATOR-MATRIX.md +136 -0
- package/docs/audit/TEST-COVERAGE-GAPS.md +334 -0
- package/docs/audit/integrations/SKIPPED.md +101 -0
- package/docs/autonomous-install.md +79 -0
- package/docs/capability-genesis.md +137 -0
- package/docs/capability-pack-schema.md +157 -0
- package/docs/commands.md +82 -0
- package/docs/deep-research-capability.md +114 -0
- package/docs/development/typescript-conventions.md +95 -0
- package/docs/host-installers.md +68 -0
- package/docs/install/aiobuilder.md +70 -0
- package/docs/install/claude-code.md +83 -0
- package/docs/install/codex.md +64 -0
- package/docs/install/gemini-cli.md +64 -0
- package/docs/install/runtime-profiles.md +83 -0
- package/docs/openlife-agent-os-blueprint.md +114 -0
- package/docs/openlife-install-backlog.md +115 -0
- package/docs/openlife-install-spec.md +306 -0
- package/docs/operations/CLOUD_CUTOVER_AUDIT.md +37 -0
- package/docs/operations/PHASE_PROGRESS_CONTINUATION.md +24 -0
- package/docs/performance-benchmarks.md +83 -0
- package/docs/planning/v1.3-capability-genesis.md +157 -0
- package/docs/plans/2026-05-05-admin-interface-professional-dark-premium-plan.md +84 -0
- package/docs/plans/2026-05-05-openlife-autonomous-domain-marketplace-masterplan.md +122 -0
- package/docs/quickstart.md +60 -0
- package/docs/release-process.md +236 -0
- package/docs/roadmap/OPENLIFE_MASTER_PLAN_CLOUD_V3.md +97 -0
- package/docs/sandboxing-research.md +117 -0
- package/docs/stories/epic-feature-audit/1.1.story.md +84 -0
- package/docs/stories/epic-feature-audit/1.2.story.md +102 -0
- package/docs/stories/epic-feature-audit/1.3.story.md +93 -0
- package/docs/stories/epic-feature-audit/1.5.story.md +121 -0
- package/docs/stories/epic-feature-audit/1.6.story.md +80 -0
- package/docs/stories/epic-feature-completeness/2.1.story.md +70 -0
- package/docs/stories/epic-feature-completeness/2.2.story.md +49 -0
- package/docs/stories/epic-feature-completeness/2.3.story.md +74 -0
- package/docs/stories/epic-feature-completeness/2.4.story.md +71 -0
- package/docs/stories/epic-feature-completeness/3.1.story.md +56 -0
- package/docs/stories/epic-feature-completeness/3.2.story.md +80 -0
- package/docs/stories/epic-feature-completeness/3.3.story.md +68 -0
- package/docs/stories/epic-feature-completeness/3.4.story.md +71 -0
- package/docs/stories/epic-feature-completeness/3.5.story.md +72 -0
- package/docs/stories/epic-feature-completeness/3.6.story.md +69 -0
- package/docs/stories/epic-feature-completeness/3.7.story.md +68 -0
- package/docs/stories/epic-feature-completeness/3.8.story.md +57 -0
- package/docs/toolset-enforcement.md +122 -0
- package/docs/v1.4-changelog.md +159 -0
- package/docs/v1.5-changelog.md +106 -0
- package/docs/v1.5-roadmap.md +121 -0
- package/docs/v1.6-changelog.md +67 -0
- package/docs/v1.6-roadmap.md +89 -0
- package/docs/v1.7-changelog.md +98 -0
- package/docs/workflow-schema.md +177 -0
- package/package.json +177 -0
- package/scripts/clean-test-pollution.js +61 -0
- package/scripts/openlife-agent-start.sh +6 -0
- package/scripts/openlife-agent.service.example +13 -0
- package/scripts/openlife-agent.supervisord.conf.example +8 -0
- package/scripts/openlife-autonomous-install.sh +29 -0
- package/scripts/postinstall-check.sh +37 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* test_performance_latency.ts — Story 12.4
|
|
4
|
+
*
|
|
5
|
+
* Lightweight latency benchmark for OpenLife hot paths. Measures P50/P95/P99
|
|
6
|
+
* for a handful of deterministic operations and persists a baseline at
|
|
7
|
+
* `.artifacts/perf-baseline.json`. Fails if any P95 regresses more than
|
|
8
|
+
* the configured threshold (default 30%) vs the saved baseline.
|
|
9
|
+
*
|
|
10
|
+
* Design constraints:
|
|
11
|
+
* • runs inside `test:all` → must complete in <5s end-to-end
|
|
12
|
+
* • no CLI spawn — measures library code directly to keep variance low
|
|
13
|
+
* • baseline auto-seeds on first run; later runs compare
|
|
14
|
+
* • configurable threshold via PERF_REGRESSION_THRESHOLD_PCT (default 30)
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const IntentClassifier_1 = require("./orchestrator/IntentClassifier");
|
|
53
|
+
const ToolsetGuard_1 = require("./orchestrator/toolset/ToolsetGuard");
|
|
54
|
+
const ProfileManager_1 = require("./cli/ProfileManager");
|
|
55
|
+
const ConditionParser_1 = require("./orchestrator/workflow/ConditionParser");
|
|
56
|
+
const WorkflowParser_1 = require("./orchestrator/workflow/WorkflowParser");
|
|
57
|
+
function nowNs() { return process.hrtime.bigint(); }
|
|
58
|
+
function nsToMs(ns) { return Number(ns) / 1_000_000; }
|
|
59
|
+
function percentile(sorted, p) {
|
|
60
|
+
if (sorted.length === 0)
|
|
61
|
+
return 0;
|
|
62
|
+
const idx = Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * p));
|
|
63
|
+
return sorted[idx];
|
|
64
|
+
}
|
|
65
|
+
function bench(name, iterations, fn) {
|
|
66
|
+
// Warm-up — discard first 5 runs to avoid JIT noise.
|
|
67
|
+
for (let i = 0; i < 5; i++)
|
|
68
|
+
fn();
|
|
69
|
+
const samples = [];
|
|
70
|
+
for (let i = 0; i < iterations; i++) {
|
|
71
|
+
const start = nowNs();
|
|
72
|
+
fn();
|
|
73
|
+
samples.push(nsToMs(nowNs() - start));
|
|
74
|
+
}
|
|
75
|
+
samples.sort((a, b) => a - b);
|
|
76
|
+
return {
|
|
77
|
+
name,
|
|
78
|
+
iterations,
|
|
79
|
+
p50ms: percentile(samples, 0.5),
|
|
80
|
+
p95ms: percentile(samples, 0.95),
|
|
81
|
+
p99ms: percentile(samples, 0.99),
|
|
82
|
+
meanMs: samples.reduce((s, v) => s + v, 0) / samples.length,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function main() {
|
|
86
|
+
const repoRoot = path.resolve(__dirname, '..');
|
|
87
|
+
const artifactsDir = path.join(repoRoot, '.artifacts');
|
|
88
|
+
fs.mkdirSync(artifactsDir, { recursive: true });
|
|
89
|
+
// Story 13.4 (v1.5) — baseline path is now env-overridable so CI can
|
|
90
|
+
// point at a checked-in `ci/perf-baseline.json` while local dev keeps
|
|
91
|
+
// the gitignored `.artifacts/perf-baseline.json`.
|
|
92
|
+
const baselineFile = process.env.OPENLIFE_PERF_BASELINE_FILE
|
|
93
|
+
? path.resolve(repoRoot, process.env.OPENLIFE_PERF_BASELINE_FILE)
|
|
94
|
+
: path.join(artifactsDir, 'perf-baseline.json');
|
|
95
|
+
fs.mkdirSync(path.dirname(baselineFile), { recursive: true });
|
|
96
|
+
// ── Benchmark 1: IntentClassifier.classify ──────────────────────
|
|
97
|
+
const classifier = new IntentClassifier_1.IntentClassifier();
|
|
98
|
+
const b1 = bench('intent_classify_cold', 200, () => {
|
|
99
|
+
classifier.classify('plan a small refactor of the auth flow');
|
|
100
|
+
});
|
|
101
|
+
// ── Benchmark 2: ToolsetGuard isAllowed (off path) ──────────────
|
|
102
|
+
(0, ToolsetGuard_1._resetToolsetGuardCache)();
|
|
103
|
+
const b2 = bench('toolset_guard_off', 500, () => {
|
|
104
|
+
(0, ToolsetGuard_1.isToolsetAllowed)('terminal');
|
|
105
|
+
});
|
|
106
|
+
// ── Benchmark 3: ProfileManager list ────────────────────────────
|
|
107
|
+
const tmpStateDir = path.join(artifactsDir, '_perf-bench-state');
|
|
108
|
+
fs.mkdirSync(tmpStateDir, { recursive: true });
|
|
109
|
+
const prevStateDir = process.env.OPENLIFE_STATE_DIR;
|
|
110
|
+
process.env.OPENLIFE_STATE_DIR = tmpStateDir;
|
|
111
|
+
const pm = new ProfileManager_1.ProfileManager();
|
|
112
|
+
// Seed 5 profiles for realistic listing.
|
|
113
|
+
for (const id of ['a', 'b', 'c', 'd', 'e']) {
|
|
114
|
+
try {
|
|
115
|
+
pm.create({ id, name: id, toolsetAllowed: ['*'] });
|
|
116
|
+
}
|
|
117
|
+
catch { /* ignore re-create */ }
|
|
118
|
+
}
|
|
119
|
+
const b3 = bench('profile_manager_list', 200, () => {
|
|
120
|
+
pm.list();
|
|
121
|
+
});
|
|
122
|
+
if (prevStateDir === undefined)
|
|
123
|
+
delete process.env.OPENLIFE_STATE_DIR;
|
|
124
|
+
else
|
|
125
|
+
process.env.OPENLIFE_STATE_DIR = prevStateDir;
|
|
126
|
+
fs.rmSync(tmpStateDir, { recursive: true, force: true });
|
|
127
|
+
// ── Benchmark 4 (Story 16.2): condition parser hot path ──────────
|
|
128
|
+
const parseResult = (0, ConditionParser_1.parseCondition)('(foo == "bar" AND baz) OR NOT qux');
|
|
129
|
+
const conditionAst = parseResult.ok ? parseResult.ast : null;
|
|
130
|
+
const conditionCtx = { foo: 'bar', baz: true, qux: false };
|
|
131
|
+
const b4 = bench('condition_parse_and_evaluate', 500, () => {
|
|
132
|
+
const r = (0, ConditionParser_1.parseCondition)('(foo == "bar" AND baz) OR NOT qux');
|
|
133
|
+
if (r.ok && r.ast)
|
|
134
|
+
(0, ConditionParser_1.evaluate)(r.ast, conditionCtx);
|
|
135
|
+
else if (conditionAst)
|
|
136
|
+
(0, ConditionParser_1.evaluate)(conditionAst, conditionCtx);
|
|
137
|
+
});
|
|
138
|
+
// ── Benchmark 5 (Story 16.2): workflow parse hot path ──────────────
|
|
139
|
+
const sampleYaml = [
|
|
140
|
+
'id: bench-wf',
|
|
141
|
+
'name: Bench Workflow',
|
|
142
|
+
'version: "1.0"',
|
|
143
|
+
'description: tiny',
|
|
144
|
+
'mode: task',
|
|
145
|
+
'steps:',
|
|
146
|
+
' - id: greet',
|
|
147
|
+
' name: greet',
|
|
148
|
+
' agent: cli',
|
|
149
|
+
' action: { kind: log, message: hi }',
|
|
150
|
+
' - id: verify',
|
|
151
|
+
' name: verify',
|
|
152
|
+
' agent: cli',
|
|
153
|
+
' action: { kind: log, message: ok }',
|
|
154
|
+
' condition: greet.success',
|
|
155
|
+
'',
|
|
156
|
+
].join('\n');
|
|
157
|
+
const b5 = bench('workflow_parse', 200, () => {
|
|
158
|
+
(0, WorkflowParser_1.parseWorkflow)(sampleYaml);
|
|
159
|
+
});
|
|
160
|
+
// ── Aggregate & persist ────────────────────────────────────────
|
|
161
|
+
const results = [b1, b2, b3, b4, b5];
|
|
162
|
+
const current = {
|
|
163
|
+
capturedAt: new Date().toISOString(),
|
|
164
|
+
benchmarks: results.reduce((acc, r) => {
|
|
165
|
+
acc[r.name] = { p50ms: r.p50ms, p95ms: r.p95ms, p99ms: r.p99ms, meanMs: r.meanMs };
|
|
166
|
+
return acc;
|
|
167
|
+
}, {}),
|
|
168
|
+
};
|
|
169
|
+
const threshold = Number(process.env.PERF_REGRESSION_THRESHOLD_PCT || 30);
|
|
170
|
+
if (!fs.existsSync(baselineFile)) {
|
|
171
|
+
fs.writeFileSync(baselineFile, JSON.stringify(current, null, 2), 'utf-8');
|
|
172
|
+
console.log('[perf] no baseline found — seeded fresh baseline.');
|
|
173
|
+
for (const r of results) {
|
|
174
|
+
console.log(`[perf] ${r.name.padEnd(28)} P50=${r.p50ms.toFixed(3)}ms P95=${r.p95ms.toFixed(3)}ms P99=${r.p99ms.toFixed(3)}ms mean=${r.meanMs.toFixed(3)}ms`);
|
|
175
|
+
}
|
|
176
|
+
console.log('TEST_PERFORMANCE_LATENCY_OK');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const baseline = JSON.parse(fs.readFileSync(baselineFile, 'utf-8'));
|
|
180
|
+
// Story 13.4 (v1.5) — absolute P95 floor below which the % gate is skipped.
|
|
181
|
+
// Sub-millisecond benchmarks are dominated by timer noise; a +30% delta on
|
|
182
|
+
// 0.001ms is meaningless. Configurable via PERF_NOISE_FLOOR_MS (default 0.5).
|
|
183
|
+
const noiseFloorMs = Number(process.env.PERF_NOISE_FLOOR_MS || 0.5);
|
|
184
|
+
const regressions = [];
|
|
185
|
+
for (const r of results) {
|
|
186
|
+
const prev = baseline.benchmarks[r.name];
|
|
187
|
+
if (!prev) {
|
|
188
|
+
console.log(`[perf] ${r.name} new — no baseline.`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (prev.p95ms < noiseFloorMs && r.p95ms < noiseFloorMs) {
|
|
192
|
+
console.log(`[perf] · ${r.name.padEnd(28)} P95 now=${r.p95ms.toFixed(3)}ms (baseline=${prev.p95ms.toFixed(3)}ms) — below noise floor ${noiseFloorMs}ms, gate skipped`);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const pctP95 = prev.p95ms > 0 ? ((r.p95ms - prev.p95ms) / prev.p95ms) * 100 : 0;
|
|
196
|
+
const mark = pctP95 > threshold ? '❌' : '✓';
|
|
197
|
+
console.log(`[perf] ${mark} ${r.name.padEnd(28)} P95 now=${r.p95ms.toFixed(3)}ms vs baseline=${prev.p95ms.toFixed(3)}ms (${pctP95 >= 0 ? '+' : ''}${pctP95.toFixed(1)}%)`);
|
|
198
|
+
if (pctP95 > threshold)
|
|
199
|
+
regressions.push(`${r.name}: P95 +${pctP95.toFixed(1)}% > threshold ${threshold}%`);
|
|
200
|
+
}
|
|
201
|
+
if (regressions.length > 0) {
|
|
202
|
+
console.error('[perf] REGRESSION DETECTED:');
|
|
203
|
+
for (const r of regressions)
|
|
204
|
+
console.error(` • ${r}`);
|
|
205
|
+
process.exitCode = 1;
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// Optionally refresh the baseline if PERF_REFRESH_BASELINE=1.
|
|
209
|
+
if (process.env.PERF_REFRESH_BASELINE === '1') {
|
|
210
|
+
fs.writeFileSync(baselineFile, JSON.stringify(current, null, 2), 'utf-8');
|
|
211
|
+
console.log('[perf] baseline refreshed.');
|
|
212
|
+
}
|
|
213
|
+
console.log('TEST_PERFORMANCE_LATENCY_OK');
|
|
214
|
+
}
|
|
215
|
+
main();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const PerformanceScorecard_1 = require("./orchestrator/PerformanceScorecard");
|
|
4
|
+
function assert(condition, message) {
|
|
5
|
+
if (!condition)
|
|
6
|
+
throw new Error(message);
|
|
7
|
+
}
|
|
8
|
+
async function main() {
|
|
9
|
+
const scorecard = new PerformanceScorecard_1.PerformanceScorecard();
|
|
10
|
+
scorecard.record({
|
|
11
|
+
entityId: 'agent-builder',
|
|
12
|
+
entityType: 'agent',
|
|
13
|
+
status: 'success',
|
|
14
|
+
durationMs: 8000,
|
|
15
|
+
reviewScore: 0.9,
|
|
16
|
+
fallbackUsed: false,
|
|
17
|
+
timestamp: new Date().toISOString()
|
|
18
|
+
});
|
|
19
|
+
scorecard.record({
|
|
20
|
+
entityId: 'agent-builder',
|
|
21
|
+
entityType: 'agent',
|
|
22
|
+
status: 'partial',
|
|
23
|
+
durationMs: 12000,
|
|
24
|
+
reviewScore: 0.6,
|
|
25
|
+
fallbackUsed: true,
|
|
26
|
+
timestamp: new Date().toISOString()
|
|
27
|
+
});
|
|
28
|
+
const aggregate = scorecard.get('agent-builder');
|
|
29
|
+
assert(!!aggregate, 'aggregate should exist');
|
|
30
|
+
assert(aggregate.runs >= 2, 'runs should accumulate');
|
|
31
|
+
assert(aggregate.avgReviewScore > 0, 'review score should be tracked');
|
|
32
|
+
assert(aggregate.fallbackRate > 0, 'fallback rate should be tracked');
|
|
33
|
+
console.log('TEST_PERFORMANCE_SCORECARD_OK');
|
|
34
|
+
}
|
|
35
|
+
main().catch((error) => {
|
|
36
|
+
console.error(error.message || error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
/*
|
|
37
|
+
* Regression test for Story 2.1 — Phase 5 v1.0 milestone.
|
|
38
|
+
*
|
|
39
|
+
* Asserts `openlife phase1-check` exits DETERMINISTICALLY (does not hang).
|
|
40
|
+
* Previously, the command would never exit because TestHarness instantiates
|
|
41
|
+
* Gateway → Telegraf, leaving event-loop handles open. Same root-cause pattern
|
|
42
|
+
* as Story 1.2 `ask` exit fix.
|
|
43
|
+
*
|
|
44
|
+
* The test uses a generous timeout (default 120s) to accommodate slow imports
|
|
45
|
+
* in WSL (Brain alone takes ~10s to require; Gateway ~21s). The bug being
|
|
46
|
+
* tested is forever-hang, not slow-but-finite.
|
|
47
|
+
*
|
|
48
|
+
* Wired into test:all via `test:phase1-check-exit` script.
|
|
49
|
+
*/
|
|
50
|
+
const child_process_1 = require("child_process");
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const CLI = path.join(process.cwd(), 'dist', 'index.js');
|
|
54
|
+
// Generous shell timeout — Brain/Gateway imports take 10-25s each in WSL.
|
|
55
|
+
// The bug is forever-hang, not slowness. If it exits within 120s, fix works.
|
|
56
|
+
const SHELL_TIMEOUT_MS = Number(process.env.OPENLIFE_TEST_PHASE1_SHELL_TIMEOUT_MS || 120000);
|
|
57
|
+
// Pass tighter internal master timeout to phase1-check
|
|
58
|
+
const INTERNAL_TIMEOUT_MS = Number(process.env.OPENLIFE_TEST_PHASE1_INTERNAL_TIMEOUT_MS || 90000);
|
|
59
|
+
function runPhase1Check() {
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
const t0 = Date.now();
|
|
62
|
+
const child = (0, child_process_1.spawn)('node', [CLI, 'phase1-check'], {
|
|
63
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
64
|
+
env: {
|
|
65
|
+
...process.env,
|
|
66
|
+
OPENLIFE_PHASE1_TIMEOUT_MS: String(INTERNAL_TIMEOUT_MS)
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Drain stdio so child doesn't block on full pipes
|
|
70
|
+
child.stdout?.on('data', () => { });
|
|
71
|
+
child.stderr?.on('data', () => { });
|
|
72
|
+
let timedOut = false;
|
|
73
|
+
const killer = setTimeout(() => {
|
|
74
|
+
timedOut = true;
|
|
75
|
+
child.kill('SIGKILL');
|
|
76
|
+
}, SHELL_TIMEOUT_MS);
|
|
77
|
+
child.on('exit', (code, signal) => {
|
|
78
|
+
clearTimeout(killer);
|
|
79
|
+
resolve({ code, signal, elapsed: Date.now() - t0, timedOut });
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function main() {
|
|
84
|
+
if (!fs.existsSync(CLI))
|
|
85
|
+
throw new Error(`MISSING_BUILD: ${CLI}`);
|
|
86
|
+
const result = await runPhase1Check();
|
|
87
|
+
if (result.timedOut) {
|
|
88
|
+
throw new Error(`PHASE1_CHECK_HUNG: process did not exit within ${SHELL_TIMEOUT_MS}ms — Story 2.1 regression`);
|
|
89
|
+
}
|
|
90
|
+
// Accept exit 0 (all checks green) OR exit 1 (some checks failed but command terminated)
|
|
91
|
+
// Reject signal-only exit (would indicate crash mid-execution)
|
|
92
|
+
if (result.code === null) {
|
|
93
|
+
throw new Error(`PHASE1_CHECK_NO_EXIT_CODE: signal=${result.signal} elapsed=${result.elapsed}ms`);
|
|
94
|
+
}
|
|
95
|
+
if (result.code !== 0 && result.code !== 1) {
|
|
96
|
+
throw new Error(`PHASE1_CHECK_UNEXPECTED_EXIT: code=${result.code} elapsed=${result.elapsed}ms (expected 0 or 1)`);
|
|
97
|
+
}
|
|
98
|
+
console.log(`TEST_PHASE1_CHECK_EXIT_OK (code=${result.code}, elapsed=${result.elapsed}ms, signal=${result.signal})`);
|
|
99
|
+
}
|
|
100
|
+
main().catch((err) => {
|
|
101
|
+
console.error('TEST_PHASE1_CHECK_EXIT_FAIL:', err?.message || err);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ExecutionBoard_1 = require("./orchestrator/ExecutionBoard");
|
|
4
|
+
function assert(condition, message) {
|
|
5
|
+
if (!condition)
|
|
6
|
+
throw new Error(message);
|
|
7
|
+
}
|
|
8
|
+
async function main() {
|
|
9
|
+
const board = new ExecutionBoard_1.ExecutionBoard();
|
|
10
|
+
board.add({
|
|
11
|
+
id: 'board-phase6-smart',
|
|
12
|
+
title: 'Testar board inteligente',
|
|
13
|
+
ownerRole: 'coo',
|
|
14
|
+
status: 'active',
|
|
15
|
+
priority: 'high',
|
|
16
|
+
dependencies: ['dep-1'],
|
|
17
|
+
slaHours: 24,
|
|
18
|
+
notes: 'item de teste'
|
|
19
|
+
});
|
|
20
|
+
board.updateStatus('board-phase6-smart', 'blocked', 'Dependência externa pendente');
|
|
21
|
+
const item = board.getAll().find((entry) => entry.id === 'board-phase6-smart');
|
|
22
|
+
assert(!!item, 'board item should exist');
|
|
23
|
+
assert(item.blockerReason === 'Dependência externa pendente', 'board should persist blocker reason');
|
|
24
|
+
assert(Array.isArray(item.dependencies) && item.dependencies.length === 1, 'board should persist dependencies');
|
|
25
|
+
assert(typeof item.ageHours === 'number', 'board should expose age hours');
|
|
26
|
+
console.log('TEST_PHASE6_BOARD_OK');
|
|
27
|
+
}
|
|
28
|
+
main().catch((error) => {
|
|
29
|
+
console.error(error.message || error);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const RoleHandoff_1 = require("./orchestrator/RoleHandoff");
|
|
4
|
+
const CadenceEngine_1 = require("./orchestrator/CadenceEngine");
|
|
5
|
+
function assert(condition, message) {
|
|
6
|
+
if (!condition)
|
|
7
|
+
throw new Error(message);
|
|
8
|
+
}
|
|
9
|
+
async function main() {
|
|
10
|
+
const handoff = new RoleHandoff_1.RoleHandoff();
|
|
11
|
+
const cadence = new CadenceEngine_1.CadenceEngine();
|
|
12
|
+
handoff.create({
|
|
13
|
+
id: 'handoff-phase6',
|
|
14
|
+
fromRole: 'cpo',
|
|
15
|
+
toRole: 'cto',
|
|
16
|
+
missionId: 'task-phase6',
|
|
17
|
+
summary: 'Transformar descoberta em execução.',
|
|
18
|
+
status: 'queued'
|
|
19
|
+
});
|
|
20
|
+
const planning = cadence.schedule('planning', 'Planning semanal', 'coo');
|
|
21
|
+
cadence.updateStatus(planning.id, 'running');
|
|
22
|
+
assert(handoff.getAll().some((item) => item.id === 'handoff-phase6'), 'handoff should persist');
|
|
23
|
+
assert(cadence.getAll().some((item) => item.id === planning.id && item.status === 'running'), 'cadence should update status');
|
|
24
|
+
console.log('TEST_PHASE6_CADENCE_OK');
|
|
25
|
+
}
|
|
26
|
+
main().catch((error) => {
|
|
27
|
+
console.error(error.message || error);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const OrgStructure_1 = require("./orchestrator/OrgStructure");
|
|
4
|
+
const ExecutionBoard_1 = require("./orchestrator/ExecutionBoard");
|
|
5
|
+
const ReleaseWorkflow_1 = require("./orchestrator/ReleaseWorkflow");
|
|
6
|
+
function assert(condition, message) {
|
|
7
|
+
if (!condition)
|
|
8
|
+
throw new Error(message);
|
|
9
|
+
}
|
|
10
|
+
async function main() {
|
|
11
|
+
const org = new OrgStructure_1.OrgStructure();
|
|
12
|
+
const board = new ExecutionBoard_1.ExecutionBoard();
|
|
13
|
+
const release = new ReleaseWorkflow_1.ReleaseWorkflow();
|
|
14
|
+
const roles = org.all();
|
|
15
|
+
assert(roles.length >= 4, 'org structure should expose core leadership roles');
|
|
16
|
+
board.add({
|
|
17
|
+
id: 'phase6-init',
|
|
18
|
+
title: 'Iniciar estrutura operacional da Fase 6',
|
|
19
|
+
ownerRole: 'coo',
|
|
20
|
+
status: 'active',
|
|
21
|
+
priority: 'high',
|
|
22
|
+
notes: 'Abrir trilho company-in-a-box'
|
|
23
|
+
});
|
|
24
|
+
const items = board.getAll();
|
|
25
|
+
assert(items.some((item) => item.id === 'phase6-init'), 'execution board should store operational items');
|
|
26
|
+
const checklist = release.create('release-phase6-bootstrap', [
|
|
27
|
+
{ name: 'build', ok: true },
|
|
28
|
+
{ name: 'tests', ok: true },
|
|
29
|
+
{ name: 'docs', ok: true }
|
|
30
|
+
]);
|
|
31
|
+
assert(checklist.approved === true, 'release checklist should approve when all checks pass');
|
|
32
|
+
console.log('TEST_PHASE6_OPS_OK');
|
|
33
|
+
}
|
|
34
|
+
main().catch((error) => {
|
|
35
|
+
console.error(error.message || error);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* test_post_mission_evaluation.ts — Story 13.1 (v1.5)
|
|
4
|
+
*
|
|
5
|
+
* Asserts:
|
|
6
|
+
* 1. OPENLIFE_POST_MISSION_EVALUATION=off short-circuits — no evaluation
|
|
7
|
+
* file is written even when a Brain key is present.
|
|
8
|
+
* 2. With no Brain key but with successCriteria, the heuristic fallback
|
|
9
|
+
* via MissionEvaluationStore.judge() writes the file.
|
|
10
|
+
* 3. With a stubbed Brain that returns a structured JSON evaluation, the
|
|
11
|
+
* Brain-derived fields land in the persisted record (source='brain').
|
|
12
|
+
* 4. Malformed Brain output falls back to the heuristic record.
|
|
13
|
+
*
|
|
14
|
+
* Drives the real `evaluateMission` via a focused harness — we instantiate
|
|
15
|
+
* a partial MissionState (only the fields evaluateMission reads) and call
|
|
16
|
+
* the private method via a thin reflection bridge to keep the test
|
|
17
|
+
* deterministic and offline.
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
36
|
+
var ownKeys = function(o) {
|
|
37
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
48
|
+
__setModuleDefault(result, mod);
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const os = __importStar(require("os"));
|
|
55
|
+
const path = __importStar(require("path"));
|
|
56
|
+
function assertTrue(cond, label) {
|
|
57
|
+
if (!cond)
|
|
58
|
+
throw new Error(`ASSERT_FAILED[${label}]`);
|
|
59
|
+
}
|
|
60
|
+
function withEnv(key, value, body) {
|
|
61
|
+
const prev = process.env[key];
|
|
62
|
+
if (value === undefined)
|
|
63
|
+
delete process.env[key];
|
|
64
|
+
else
|
|
65
|
+
process.env[key] = value;
|
|
66
|
+
return Promise.resolve(body()).finally(() => {
|
|
67
|
+
if (prev === undefined)
|
|
68
|
+
delete process.env[key];
|
|
69
|
+
else
|
|
70
|
+
process.env[key] = prev;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function main() {
|
|
74
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'post-mission-eval-'));
|
|
75
|
+
process.env.OPENLIFE_STATE_DIR = tmp;
|
|
76
|
+
try {
|
|
77
|
+
// Defer requires until env is set so EnterpriseAgenticCore picks tmp dir.
|
|
78
|
+
const { OrchestrationLoop } = require('./orchestrator/OrchestrationLoop');
|
|
79
|
+
const { MissionEvaluationStore } = require('./orchestrator/EnterpriseAgenticCore');
|
|
80
|
+
// Constructing OrchestrationLoop is heavy (many deps). For Story 13.1 we
|
|
81
|
+
// only need the evaluateMission method, so we reach into the prototype
|
|
82
|
+
// directly with a minimal `this` shape.
|
|
83
|
+
const evaluateMission = OrchestrationLoop.prototype.evaluateMission;
|
|
84
|
+
const parseEvalJson = OrchestrationLoop.prototype.parseEvaluationJson;
|
|
85
|
+
const baseState = {
|
|
86
|
+
taskId: 'mission-001',
|
|
87
|
+
goal: 'investigate cold-start latency',
|
|
88
|
+
status: 'success',
|
|
89
|
+
successCriteria: ['root cause found', 'fix proposed'],
|
|
90
|
+
consequenceThoughtTrace: { snapshots: [{ note: 'looked at metrics' }] },
|
|
91
|
+
reviewFindings: [{ approved: true, critique: 'looks good' }],
|
|
92
|
+
};
|
|
93
|
+
const store = new MissionEvaluationStore(tmp);
|
|
94
|
+
const evalPath = (id) => path.join(store.dir(), `${id}.json`);
|
|
95
|
+
// ── Scenario 1: parseEvaluationJson unit checks ────────────────────
|
|
96
|
+
// Verifies the JSON-extraction helper that gates Brain output.
|
|
97
|
+
const ok = parseEvalJson.call({}, 'noise {"score":42,"verdict":"needs_iteration","risks":["a"],"rationale":"r"} trailing');
|
|
98
|
+
assertTrue(ok !== null && ok.score === 42, '[13.1] parser handles embedded JSON');
|
|
99
|
+
const wrongVerdict = parseEvalJson.call({}, '{"score":50,"verdict":"thumbs_up","risks":[],"rationale":""}');
|
|
100
|
+
assertTrue(wrongVerdict === null, '[13.1] parser rejects unknown verdict');
|
|
101
|
+
const noScore = parseEvalJson.call({}, '{"verdict":"ready_for_review","risks":[],"rationale":"x"}');
|
|
102
|
+
assertTrue(noScore === null, '[13.1] parser rejects missing score');
|
|
103
|
+
const clamped = parseEvalJson.call({}, '{"score":150,"verdict":"ready_for_review","risks":[],"rationale":""}');
|
|
104
|
+
assertTrue(clamped && clamped.score === 100, '[13.1] parser clamps score to <=100');
|
|
105
|
+
const garbage = parseEvalJson.call({}, 'totally not json');
|
|
106
|
+
assertTrue(garbage === null, '[13.1] parser returns null on garbage input');
|
|
107
|
+
console.log('[13.1] parseEvaluationJson unit checks pass ✓');
|
|
108
|
+
// ── Scenario 2: no Brain key → heuristic fallback ──────────────────
|
|
109
|
+
delete process.env.OPENAI_API_KEY;
|
|
110
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
111
|
+
delete process.env.GEMINI_API_KEY;
|
|
112
|
+
delete process.env.OPENROUTER_API_KEY;
|
|
113
|
+
delete process.env.OLLAMA_URL;
|
|
114
|
+
{
|
|
115
|
+
const id = 'mission-heuristic';
|
|
116
|
+
await evaluateMission.call({ parseEvaluationJson: parseEvalJson }, { ...baseState, taskId: id });
|
|
117
|
+
assertTrue(fs.existsSync(evalPath(id)), '[13.1] heuristic fallback wrote eval file');
|
|
118
|
+
const eval1 = JSON.parse(fs.readFileSync(evalPath(id), 'utf-8'));
|
|
119
|
+
assertTrue(typeof eval1.score === 'number' && eval1.score >= 0 && eval1.score <= 100, '[13.1] heuristic score in [0,100]');
|
|
120
|
+
assertTrue(Array.isArray(eval1.criteria) && eval1.criteria.length === 2, '[13.1] heuristic criteria preserved');
|
|
121
|
+
}
|
|
122
|
+
console.log('[13.1] no-key heuristic fallback writes record ✓');
|
|
123
|
+
// ── Scenario 3: stubbed Brain → structured evaluation lands ────────
|
|
124
|
+
// We stub Brain by monkey-patching the require cache.
|
|
125
|
+
const brainPath = require.resolve('./orchestrator/Brain');
|
|
126
|
+
const origCache = require.cache[brainPath];
|
|
127
|
+
require.cache[brainPath] = {
|
|
128
|
+
...origCache,
|
|
129
|
+
exports: {
|
|
130
|
+
Brain: class {
|
|
131
|
+
isAnyProviderAvailable() { return true; }
|
|
132
|
+
async think() {
|
|
133
|
+
return 'Sure! Here is the eval: {"score":88,"verdict":"ready_for_review","risks":["regression in cold path"],"rationale":"all criteria met"}';
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
const id = 'mission-brain';
|
|
140
|
+
await evaluateMission.call({ parseEvaluationJson: parseEvalJson }, { ...baseState, taskId: id });
|
|
141
|
+
assertTrue(fs.existsSync(evalPath(id)), '[13.1] brain path wrote eval file');
|
|
142
|
+
const evalBrain = JSON.parse(fs.readFileSync(evalPath(id), 'utf-8'));
|
|
143
|
+
assertTrue(evalBrain.source === 'brain', `[13.1] eval source=brain (got ${evalBrain.source})`);
|
|
144
|
+
assertTrue(evalBrain.score === 88, `[13.1] brain score landed (got ${evalBrain.score})`);
|
|
145
|
+
assertTrue(evalBrain.verdict === 'ready_for_review', `[13.1] brain verdict landed (got ${evalBrain.verdict})`);
|
|
146
|
+
assertTrue(Array.isArray(evalBrain.risks) && evalBrain.risks[0] === 'regression in cold path', '[13.1] brain risks landed');
|
|
147
|
+
assertTrue(typeof evalBrain.rationale === 'string' && evalBrain.rationale.includes('criteria met'), '[13.1] brain rationale landed');
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
if (origCache)
|
|
151
|
+
require.cache[brainPath] = origCache;
|
|
152
|
+
else
|
|
153
|
+
delete require.cache[brainPath];
|
|
154
|
+
}
|
|
155
|
+
console.log('[13.1] brain-derived structured evaluation persisted ✓');
|
|
156
|
+
// ── Scenario 4: garbage Brain output → heuristic fallback ─────────
|
|
157
|
+
require.cache[brainPath] = {
|
|
158
|
+
...origCache,
|
|
159
|
+
exports: {
|
|
160
|
+
Brain: class {
|
|
161
|
+
isAnyProviderAvailable() { return true; }
|
|
162
|
+
async think() { return 'I cannot parse this. Sorry.'; }
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
try {
|
|
167
|
+
const id = 'mission-garbage';
|
|
168
|
+
await evaluateMission.call({ parseEvaluationJson: parseEvalJson }, { ...baseState, taskId: id });
|
|
169
|
+
assertTrue(fs.existsSync(evalPath(id)), '[13.1] garbage brain fell back to heuristic file');
|
|
170
|
+
const evalGarbage = JSON.parse(fs.readFileSync(evalPath(id), 'utf-8'));
|
|
171
|
+
assertTrue(evalGarbage.source !== 'brain', '[13.1] garbage path is not source=brain (heuristic fallback)');
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
if (origCache)
|
|
175
|
+
require.cache[brainPath] = origCache;
|
|
176
|
+
else
|
|
177
|
+
delete require.cache[brainPath];
|
|
178
|
+
}
|
|
179
|
+
console.log('[13.1] malformed brain output falls back cleanly ✓');
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
delete process.env.OPENLIFE_STATE_DIR;
|
|
183
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
184
|
+
}
|
|
185
|
+
console.log('TEST_POST_MISSION_EVALUATION_OK');
|
|
186
|
+
}
|
|
187
|
+
main().catch((err) => {
|
|
188
|
+
console.error('[post-mission-evaluation] FAILED:', err instanceof Error ? err.message : err);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
});
|