@hongmaple0820/med-scale-research-os 0.43.0
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/.scale/mcp-servers.yaml +144 -0
- package/.scale/skills.json +830 -0
- package/.scale/verification.json +52 -0
- package/LICENSE +15 -0
- package/README.en.md +156 -0
- package/README.md +156 -0
- package/dist/adapters/AiderAdapter.d.ts +22 -0
- package/dist/adapters/AiderAdapter.js +262 -0
- package/dist/adapters/AiderAdapter.js.map +1 -0
- package/dist/adapters/AntigravityAdapter.d.ts +4 -0
- package/dist/adapters/AntigravityAdapter.js +21 -0
- package/dist/adapters/AntigravityAdapter.js.map +1 -0
- package/dist/adapters/ClaudeCodeAdapter.d.ts +54 -0
- package/dist/adapters/ClaudeCodeAdapter.js +185 -0
- package/dist/adapters/ClaudeCodeAdapter.js.map +1 -0
- package/dist/adapters/ClineAdapter.d.ts +4 -0
- package/dist/adapters/ClineAdapter.js +20 -0
- package/dist/adapters/ClineAdapter.js.map +1 -0
- package/dist/adapters/CodexAdapter.d.ts +15 -0
- package/dist/adapters/CodexAdapter.js +160 -0
- package/dist/adapters/CodexAdapter.js.map +1 -0
- package/dist/adapters/CursorAdapter.d.ts +14 -0
- package/dist/adapters/CursorAdapter.js +171 -0
- package/dist/adapters/CursorAdapter.js.map +1 -0
- package/dist/adapters/DeepSeekTuiAdapter.d.ts +19 -0
- package/dist/adapters/DeepSeekTuiAdapter.js +263 -0
- package/dist/adapters/DeepSeekTuiAdapter.js.map +1 -0
- package/dist/adapters/DoubaoAdapter.d.ts +14 -0
- package/dist/adapters/DoubaoAdapter.js +184 -0
- package/dist/adapters/DoubaoAdapter.js.map +1 -0
- package/dist/adapters/GeminiAdapter.d.ts +14 -0
- package/dist/adapters/GeminiAdapter.js +163 -0
- package/dist/adapters/GeminiAdapter.js.map +1 -0
- package/dist/adapters/GenericProjectAgentAdapter.d.ts +29 -0
- package/dist/adapters/GenericProjectAgentAdapter.js +204 -0
- package/dist/adapters/GenericProjectAgentAdapter.js.map +1 -0
- package/dist/adapters/HermesAdapter.d.ts +14 -0
- package/dist/adapters/HermesAdapter.js +163 -0
- package/dist/adapters/HermesAdapter.js.map +1 -0
- package/dist/adapters/JCodeAdapter.d.ts +4 -0
- package/dist/adapters/JCodeAdapter.js +19 -0
- package/dist/adapters/JCodeAdapter.js.map +1 -0
- package/dist/adapters/KiloCodeAdapter.d.ts +4 -0
- package/dist/adapters/KiloCodeAdapter.js +20 -0
- package/dist/adapters/KiloCodeAdapter.js.map +1 -0
- package/dist/adapters/KimiAdapter.d.ts +14 -0
- package/dist/adapters/KimiAdapter.js +183 -0
- package/dist/adapters/KimiAdapter.js.map +1 -0
- package/dist/adapters/KiroAdapter.d.ts +14 -0
- package/dist/adapters/KiroAdapter.js +180 -0
- package/dist/adapters/KiroAdapter.js.map +1 -0
- package/dist/adapters/OpenClawAdapter.d.ts +14 -0
- package/dist/adapters/OpenClawAdapter.js +163 -0
- package/dist/adapters/OpenClawAdapter.js.map +1 -0
- package/dist/adapters/OpenCodeAdapter.d.ts +14 -0
- package/dist/adapters/OpenCodeAdapter.js +172 -0
- package/dist/adapters/OpenCodeAdapter.js.map +1 -0
- package/dist/adapters/QCoderAdapter.d.ts +14 -0
- package/dist/adapters/QCoderAdapter.js +159 -0
- package/dist/adapters/QCoderAdapter.js.map +1 -0
- package/dist/adapters/QoderAdapter.d.ts +4 -0
- package/dist/adapters/QoderAdapter.js +21 -0
- package/dist/adapters/QoderAdapter.js.map +1 -0
- package/dist/adapters/TraeAdapter.d.ts +14 -0
- package/dist/adapters/TraeAdapter.js +159 -0
- package/dist/adapters/TraeAdapter.js.map +1 -0
- package/dist/adapters/VSCAdapter.d.ts +14 -0
- package/dist/adapters/VSCAdapter.js +159 -0
- package/dist/adapters/VSCAdapter.js.map +1 -0
- package/dist/adapters/WindsurfAdapter.d.ts +14 -0
- package/dist/adapters/WindsurfAdapter.js +185 -0
- package/dist/adapters/WindsurfAdapter.js.map +1 -0
- package/dist/adapters/WorkBuddyAdapter.d.ts +14 -0
- package/dist/adapters/WorkBuddyAdapter.js +159 -0
- package/dist/adapters/WorkBuddyAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +32 -0
- package/dist/adapters/index.js +87 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/agents/AgentChannel.d.ts +43 -0
- package/dist/agents/AgentChannel.js +136 -0
- package/dist/agents/AgentChannel.js.map +1 -0
- package/dist/agents/AgentCoordinator.d.ts +29 -0
- package/dist/agents/AgentCoordinator.js +136 -0
- package/dist/agents/AgentCoordinator.js.map +1 -0
- package/dist/agents/AgentDispatcher.d.ts +24 -0
- package/dist/agents/AgentDispatcher.js +112 -0
- package/dist/agents/AgentDispatcher.js.map +1 -0
- package/dist/agents/AgentManager.d.ts +14 -0
- package/dist/agents/AgentManager.js +85 -0
- package/dist/agents/AgentManager.js.map +1 -0
- package/dist/agents/AgentPool.d.ts +59 -0
- package/dist/agents/AgentPool.js +192 -0
- package/dist/agents/AgentPool.js.map +1 -0
- package/dist/agents/AgentRegistry.d.ts +20 -0
- package/dist/agents/AgentRegistry.js +36 -0
- package/dist/agents/AgentRegistry.js.map +1 -0
- package/dist/agents/AgentSourceLoader.d.ts +73 -0
- package/dist/agents/AgentSourceLoader.js +103 -0
- package/dist/agents/AgentSourceLoader.js.map +1 -0
- package/dist/agents/IAgent.d.ts +53 -0
- package/dist/agents/IAgent.js +4 -0
- package/dist/agents/IAgent.js.map +1 -0
- package/dist/agents/LeadershipPresets.d.ts +16 -0
- package/dist/agents/LeadershipPresets.js +152 -0
- package/dist/agents/LeadershipPresets.js.map +1 -0
- package/dist/agents/definitions/debugger.d.ts +2 -0
- package/dist/agents/definitions/debugger.js +6 -0
- package/dist/agents/definitions/debugger.js.map +1 -0
- package/dist/agents/definitions/doc-writer.d.ts +2 -0
- package/dist/agents/definitions/doc-writer.js +6 -0
- package/dist/agents/definitions/doc-writer.js.map +1 -0
- package/dist/agents/definitions/implementer.d.ts +2 -0
- package/dist/agents/definitions/implementer.js +6 -0
- package/dist/agents/definitions/implementer.js.map +1 -0
- package/dist/agents/definitions/planner.d.ts +2 -0
- package/dist/agents/definitions/planner.js +6 -0
- package/dist/agents/definitions/planner.js.map +1 -0
- package/dist/agents/definitions/researcher.d.ts +2 -0
- package/dist/agents/definitions/researcher.js +6 -0
- package/dist/agents/definitions/researcher.js.map +1 -0
- package/dist/agents/definitions/reviewer.d.ts +2 -0
- package/dist/agents/definitions/reviewer.js +6 -0
- package/dist/agents/definitions/reviewer.js.map +1 -0
- package/dist/agents/definitions/security.d.ts +2 -0
- package/dist/agents/definitions/security.js +6 -0
- package/dist/agents/definitions/security.js.map +1 -0
- package/dist/agents/definitions/tester.d.ts +2 -0
- package/dist/agents/definitions/tester.js +6 -0
- package/dist/agents/definitions/tester.js.map +1 -0
- package/dist/agents/index.d.ts +23 -0
- package/dist/agents/index.js +44 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/profiles.d.ts +26 -0
- package/dist/agents/profiles.js +197 -0
- package/dist/agents/profiles.js.map +1 -0
- package/dist/agents/types.d.ts +262 -0
- package/dist/agents/types.js +4 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/api/cli.d.ts +2 -0
- package/dist/api/cli.js +6678 -0
- package/dist/api/cli.js.map +1 -0
- package/dist/api/doctor.d.ts +83 -0
- package/dist/api/doctor.js +982 -0
- package/dist/api/doctor.js.map +1 -0
- package/dist/api/mcp.d.ts +32 -0
- package/dist/api/mcp.js +223 -0
- package/dist/api/mcp.js.map +1 -0
- package/dist/api/medscale.d.ts +2 -0
- package/dist/api/medscale.js +20 -0
- package/dist/api/medscale.js.map +1 -0
- package/dist/api/quickstart.d.ts +86 -0
- package/dist/api/quickstart.js +291 -0
- package/dist/api/quickstart.js.map +1 -0
- package/dist/artifact/fsm.d.ts +41 -0
- package/dist/artifact/fsm.js +221 -0
- package/dist/artifact/fsm.js.map +1 -0
- package/dist/artifact/fsmDefinitions.d.ts +18 -0
- package/dist/artifact/fsmDefinitions.js +296 -0
- package/dist/artifact/fsmDefinitions.js.map +1 -0
- package/dist/artifact/sqliteStore.d.ts +61 -0
- package/dist/artifact/sqliteStore.js +381 -0
- package/dist/artifact/sqliteStore.js.map +1 -0
- package/dist/artifact/store.d.ts +49 -0
- package/dist/artifact/store.js +116 -0
- package/dist/artifact/store.js.map +1 -0
- package/dist/artifact/types.d.ts +535 -0
- package/dist/artifact/types.js +74 -0
- package/dist/artifact/types.js.map +1 -0
- package/dist/bootstrap/DependencyBootstrap.d.ts +112 -0
- package/dist/bootstrap/DependencyBootstrap.js +1046 -0
- package/dist/bootstrap/DependencyBootstrap.js.map +1 -0
- package/dist/bootstrap/DependencyBootstrapRenderer.d.ts +3 -0
- package/dist/bootstrap/DependencyBootstrapRenderer.js +138 -0
- package/dist/bootstrap/DependencyBootstrapRenderer.js.map +1 -0
- package/dist/bridge/PythonBridge.d.ts +80 -0
- package/dist/bridge/PythonBridge.js +437 -0
- package/dist/bridge/PythonBridge.js.map +1 -0
- package/dist/bridge/index.d.ts +2 -0
- package/dist/bridge/index.js +7 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/bridge/medicalWorkflows.d.ts +29 -0
- package/dist/bridge/medicalWorkflows.js +156 -0
- package/dist/bridge/medicalWorkflows.js.map +1 -0
- package/dist/bridge/types.d.ts +381 -0
- package/dist/bridge/types.js +113 -0
- package/dist/bridge/types.js.map +1 -0
- package/dist/cache/ScanCache.d.ts +41 -0
- package/dist/cache/ScanCache.js +120 -0
- package/dist/cache/ScanCache.js.map +1 -0
- package/dist/capabilities/BrowserCapability.d.ts +30 -0
- package/dist/capabilities/BrowserCapability.js +73 -0
- package/dist/capabilities/BrowserCapability.js.map +1 -0
- package/dist/capabilities/BrowserQACapability.d.ts +165 -0
- package/dist/capabilities/BrowserQACapability.js +438 -0
- package/dist/capabilities/BrowserQACapability.js.map +1 -0
- package/dist/capabilities/CapabilityRegistry.d.ts +17 -0
- package/dist/capabilities/CapabilityRegistry.js +65 -0
- package/dist/capabilities/CapabilityRegistry.js.map +1 -0
- package/dist/capabilities/ComputerCapability.d.ts +28 -0
- package/dist/capabilities/ComputerCapability.js +40 -0
- package/dist/capabilities/ComputerCapability.js.map +1 -0
- package/dist/capabilities/InstalledSkillsIntegration.d.ts +69 -0
- package/dist/capabilities/InstalledSkillsIntegration.js +240 -0
- package/dist/capabilities/InstalledSkillsIntegration.js.map +1 -0
- package/dist/capabilities/SearchCapability.d.ts +46 -0
- package/dist/capabilities/SearchCapability.js +88 -0
- package/dist/capabilities/SearchCapability.js.map +1 -0
- package/dist/capabilities/index.d.ts +6 -0
- package/dist/capabilities/index.js +9 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/types.d.ts +92 -0
- package/dist/capabilities/types.js +7 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/cli/autofixCommands.d.ts +22 -0
- package/dist/cli/autofixCommands.js +32 -0
- package/dist/cli/autofixCommands.js.map +1 -0
- package/dist/cli/cortexCommands.d.ts +71 -0
- package/dist/cli/cortexCommands.js +335 -0
- package/dist/cli/cortexCommands.js.map +1 -0
- package/dist/cli/costCommands.d.ts +13 -0
- package/dist/cli/costCommands.js +48 -0
- package/dist/cli/costCommands.js.map +1 -0
- package/dist/cli/evolutionCommands.d.ts +112 -0
- package/dist/cli/evolutionCommands.js +246 -0
- package/dist/cli/evolutionCommands.js.map +1 -0
- package/dist/cli/gateStatusCommands.d.ts +1 -0
- package/dist/cli/gateStatusCommands.js +52 -0
- package/dist/cli/gateStatusCommands.js.map +1 -0
- package/dist/cli/liteCommands.d.ts +81 -0
- package/dist/cli/liteCommands.js +148 -0
- package/dist/cli/liteCommands.js.map +1 -0
- package/dist/cli/orchCommands.d.ts +43 -0
- package/dist/cli/orchCommands.js +135 -0
- package/dist/cli/orchCommands.js.map +1 -0
- package/dist/cli/phaseCommands.d.ts +248 -0
- package/dist/cli/phaseCommands.js +1878 -0
- package/dist/cli/phaseCommands.js.map +1 -0
- package/dist/cli/promptCommands.d.ts +1 -0
- package/dist/cli/promptCommands.js +57 -0
- package/dist/cli/promptCommands.js.map +1 -0
- package/dist/cli/qaCommands.d.ts +22 -0
- package/dist/cli/qaCommands.js +84 -0
- package/dist/cli/qaCommands.js.map +1 -0
- package/dist/cli/quickstartCommands.d.ts +17 -0
- package/dist/cli/quickstartCommands.js +47 -0
- package/dist/cli/quickstartCommands.js.map +1 -0
- package/dist/cli/runCommand.d.ts +39 -0
- package/dist/cli/runCommand.js +113 -0
- package/dist/cli/runCommand.js.map +1 -0
- package/dist/cli/scoreCommands.d.ts +1 -0
- package/dist/cli/scoreCommands.js +112 -0
- package/dist/cli/scoreCommands.js.map +1 -0
- package/dist/cli/shieldCommands.d.ts +30 -0
- package/dist/cli/shieldCommands.js +212 -0
- package/dist/cli/shieldCommands.js.map +1 -0
- package/dist/cli/targetCommands.d.ts +552 -0
- package/dist/cli/targetCommands.js +3173 -0
- package/dist/cli/targetCommands.js.map +1 -0
- package/dist/cli/tuiCommands.d.ts +7 -0
- package/dist/cli/tuiCommands.js +33 -0
- package/dist/cli/tuiCommands.js.map +1 -0
- package/dist/cli/vibeCommands.d.ts +64 -0
- package/dist/cli/vibeCommands.js +221 -0
- package/dist/cli/vibeCommands.js.map +1 -0
- package/dist/codegraph/CodeIntelligence.d.ts +147 -0
- package/dist/codegraph/CodeIntelligence.js +681 -0
- package/dist/codegraph/CodeIntelligence.js.map +1 -0
- package/dist/config/profiles.d.ts +64 -0
- package/dist/config/profiles.js +223 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/context/AntiPatternRegistry.d.ts +38 -0
- package/dist/context/AntiPatternRegistry.js +203 -0
- package/dist/context/AntiPatternRegistry.js.map +1 -0
- package/dist/context/CavemanCompressor.d.ts +20 -0
- package/dist/context/CavemanCompressor.js +14 -0
- package/dist/context/CavemanCompressor.js.map +1 -0
- package/dist/context/ContextBudget.d.ts +128 -0
- package/dist/context/ContextBudget.js +423 -0
- package/dist/context/ContextBudget.js.map +1 -0
- package/dist/context/ContextBuilder.d.ts +71 -0
- package/dist/context/ContextBuilder.js +372 -0
- package/dist/context/ContextBuilder.js.map +1 -0
- package/dist/context/ContextCompiler.d.ts +34 -0
- package/dist/context/ContextCompiler.js +120 -0
- package/dist/context/ContextCompiler.js.map +1 -0
- package/dist/context/ProjectAnatomy.d.ts +18 -0
- package/dist/context/ProjectAnatomy.js +287 -0
- package/dist/context/ProjectAnatomy.js.map +1 -0
- package/dist/context/SessionStartSequence.d.ts +54 -0
- package/dist/context/SessionStartSequence.js +162 -0
- package/dist/context/SessionStartSequence.js.map +1 -0
- package/dist/core/ExternalCommand.d.ts +9 -0
- package/dist/core/ExternalCommand.js +70 -0
- package/dist/core/ExternalCommand.js.map +1 -0
- package/dist/core/GbrainRuntime.d.ts +25 -0
- package/dist/core/GbrainRuntime.js +270 -0
- package/dist/core/GbrainRuntime.js.map +1 -0
- package/dist/core/container.d.ts +14 -0
- package/dist/core/container.js +35 -0
- package/dist/core/container.js.map +1 -0
- package/dist/core/eventBus.d.ts +60 -0
- package/dist/core/eventBus.js +157 -0
- package/dist/core/eventBus.js.map +1 -0
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +51 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/cortex/GovernanceMetrics.d.ts +66 -0
- package/dist/cortex/GovernanceMetrics.js +230 -0
- package/dist/cortex/GovernanceMetrics.js.map +1 -0
- package/dist/cortex/InstinctExtractor.d.ts +61 -0
- package/dist/cortex/InstinctExtractor.js +184 -0
- package/dist/cortex/InstinctExtractor.js.map +1 -0
- package/dist/cortex/InstinctStore.d.ts +54 -0
- package/dist/cortex/InstinctStore.js +266 -0
- package/dist/cortex/InstinctStore.js.map +1 -0
- package/dist/cortex/ReflexionEngine.d.ts +34 -0
- package/dist/cortex/ReflexionEngine.js +157 -0
- package/dist/cortex/ReflexionEngine.js.map +1 -0
- package/dist/cortex/SessionInjector.d.ts +44 -0
- package/dist/cortex/SessionInjector.js +127 -0
- package/dist/cortex/SessionInjector.js.map +1 -0
- package/dist/cortex/adapters/ClaudeAdapter.d.ts +17 -0
- package/dist/cortex/adapters/ClaudeAdapter.js +61 -0
- package/dist/cortex/adapters/ClaudeAdapter.js.map +1 -0
- package/dist/cortex/adapters/CodexAdapter.d.ts +10 -0
- package/dist/cortex/adapters/CodexAdapter.js +52 -0
- package/dist/cortex/adapters/CodexAdapter.js.map +1 -0
- package/dist/cortex/adapters/CursorAdapter.d.ts +10 -0
- package/dist/cortex/adapters/CursorAdapter.js +46 -0
- package/dist/cortex/adapters/CursorAdapter.js.map +1 -0
- package/dist/cortex/adapters/GeminiAdapter.d.ts +11 -0
- package/dist/cortex/adapters/GeminiAdapter.js +48 -0
- package/dist/cortex/adapters/GeminiAdapter.js.map +1 -0
- package/dist/dashboard/DashboardServer.d.ts +86 -0
- package/dist/dashboard/DashboardServer.js +380 -0
- package/dist/dashboard/DashboardServer.js.map +1 -0
- package/dist/dashboard/MedicalWorkflowData.d.ts +155 -0
- package/dist/dashboard/MedicalWorkflowData.js +664 -0
- package/dist/dashboard/MedicalWorkflowData.js.map +1 -0
- package/dist/dashboard/MetricsAggregator.d.ts +38 -0
- package/dist/dashboard/MetricsAggregator.js +99 -0
- package/dist/dashboard/MetricsAggregator.js.map +1 -0
- package/dist/dashboard/index.d.ts +4 -0
- package/dist/dashboard/index.js +3 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/server.d.ts +52 -0
- package/dist/dashboard/server.js +84 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/env/EnvironmentDoctor.d.ts +66 -0
- package/dist/env/EnvironmentDoctor.js +581 -0
- package/dist/env/EnvironmentDoctor.js.map +1 -0
- package/dist/eval/BenchmarkPublisher.d.ts +25 -0
- package/dist/eval/BenchmarkPublisher.js +27 -0
- package/dist/eval/BenchmarkPublisher.js.map +1 -0
- package/dist/eval/WorkflowEval.d.ts +161 -0
- package/dist/eval/WorkflowEval.js +377 -0
- package/dist/eval/WorkflowEval.js.map +1 -0
- package/dist/evolution/AutoDefectCreator.d.ts +43 -0
- package/dist/evolution/AutoDefectCreator.js +157 -0
- package/dist/evolution/AutoDefectCreator.js.map +1 -0
- package/dist/evolution/BehaviorTracker.d.ts +46 -0
- package/dist/evolution/BehaviorTracker.js +67 -0
- package/dist/evolution/BehaviorTracker.js.map +1 -0
- package/dist/evolution/EvolutionEngine.d.ts +102 -0
- package/dist/evolution/EvolutionEngine.js +326 -0
- package/dist/evolution/EvolutionEngine.js.map +1 -0
- package/dist/evolution/EvolutionEvaluator.d.ts +61 -0
- package/dist/evolution/EvolutionEvaluator.js +118 -0
- package/dist/evolution/EvolutionEvaluator.js.map +1 -0
- package/dist/evolution/LessonValidator.d.ts +36 -0
- package/dist/evolution/LessonValidator.js +132 -0
- package/dist/evolution/LessonValidator.js.map +1 -0
- package/dist/evolution/PatternExtractor.d.ts +40 -0
- package/dist/evolution/PatternExtractor.js +83 -0
- package/dist/evolution/PatternExtractor.js.map +1 -0
- package/dist/evolution/RuleMaturity.d.ts +39 -0
- package/dist/evolution/RuleMaturity.js +70 -0
- package/dist/evolution/RuleMaturity.js.map +1 -0
- package/dist/evolution/SessionLearnings.d.ts +70 -0
- package/dist/evolution/SessionLearnings.js +217 -0
- package/dist/evolution/SessionLearnings.js.map +1 -0
- package/dist/evolution/SkillCreator.d.ts +75 -0
- package/dist/evolution/SkillCreator.js +219 -0
- package/dist/evolution/SkillCreator.js.map +1 -0
- package/dist/fsm/FSMAgentBridge.d.ts +59 -0
- package/dist/fsm/FSMAgentBridge.js +193 -0
- package/dist/fsm/FSMAgentBridge.js.map +1 -0
- package/dist/fsm/index.d.ts +2 -0
- package/dist/fsm/index.js +3 -0
- package/dist/fsm/index.js.map +1 -0
- package/dist/governance/GovernanceRoi.d.ts +30 -0
- package/dist/governance/GovernanceRoi.js +102 -0
- package/dist/governance/GovernanceRoi.js.map +1 -0
- package/dist/governance/ProgressiveGovernance.d.ts +22 -0
- package/dist/governance/ProgressiveGovernance.js +159 -0
- package/dist/governance/ProgressiveGovernance.js.map +1 -0
- package/dist/guardrails/ActiveRedTeam.d.ts +46 -0
- package/dist/guardrails/ActiveRedTeam.js +203 -0
- package/dist/guardrails/ActiveRedTeam.js.map +1 -0
- package/dist/guardrails/DependencyAuditor.d.ts +68 -0
- package/dist/guardrails/DependencyAuditor.js +378 -0
- package/dist/guardrails/DependencyAuditor.js.map +1 -0
- package/dist/guardrails/DetectorEnhanced.d.ts +111 -0
- package/dist/guardrails/DetectorEnhanced.js +202 -0
- package/dist/guardrails/DetectorEnhanced.js.map +1 -0
- package/dist/guardrails/GateEvaluator.d.ts +18 -0
- package/dist/guardrails/GateEvaluator.js +129 -0
- package/dist/guardrails/GateEvaluator.js.map +1 -0
- package/dist/guardrails/Gateway.d.ts +26 -0
- package/dist/guardrails/Gateway.js +56 -0
- package/dist/guardrails/Gateway.js.map +1 -0
- package/dist/guardrails/OWASPDetector.d.ts +58 -0
- package/dist/guardrails/OWASPDetector.js +508 -0
- package/dist/guardrails/OWASPDetector.js.map +1 -0
- package/dist/guardrails/ReviewEnforcer.d.ts +52 -0
- package/dist/guardrails/ReviewEnforcer.js +117 -0
- package/dist/guardrails/ReviewEnforcer.js.map +1 -0
- package/dist/guardrails/advancedDetectors.d.ts +38 -0
- package/dist/guardrails/advancedDetectors.js +188 -0
- package/dist/guardrails/advancedDetectors.js.map +1 -0
- package/dist/guardrails/detectors.d.ts +34 -0
- package/dist/guardrails/detectors.js +332 -0
- package/dist/guardrails/detectors.js.map +1 -0
- package/dist/guardrails/roles.d.ts +4 -0
- package/dist/guardrails/roles.js +54 -0
- package/dist/guardrails/roles.js.map +1 -0
- package/dist/hooks/BugPatternDetector.d.ts +36 -0
- package/dist/hooks/BugPatternDetector.js +207 -0
- package/dist/hooks/BugPatternDetector.js.map +1 -0
- package/dist/hooks/HookDeployer.d.ts +44 -0
- package/dist/hooks/HookDeployer.js +144 -0
- package/dist/hooks/HookDeployer.js.map +1 -0
- package/dist/hooks/HookGeneratorEnhanced.d.ts +67 -0
- package/dist/hooks/HookGeneratorEnhanced.js +641 -0
- package/dist/hooks/HookGeneratorEnhanced.js.map +1 -0
- package/dist/hooks/WorkflowHooksManager.d.ts +30 -0
- package/dist/hooks/WorkflowHooksManager.js +160 -0
- package/dist/hooks/WorkflowHooksManager.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/i18n/Language.d.ts +9 -0
- package/dist/i18n/Language.js +38 -0
- package/dist/i18n/Language.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/CerebrumManager.d.ts +25 -0
- package/dist/knowledge/CerebrumManager.js +127 -0
- package/dist/knowledge/CerebrumManager.js.map +1 -0
- package/dist/knowledge/GraphifyKnowledgeBase.d.ts +38 -0
- package/dist/knowledge/GraphifyKnowledgeBase.js +409 -0
- package/dist/knowledge/GraphifyKnowledgeBase.js.map +1 -0
- package/dist/knowledge/KnowledgeBase.d.ts +51 -0
- package/dist/knowledge/KnowledgeBase.js +182 -0
- package/dist/knowledge/KnowledgeBase.js.map +1 -0
- package/dist/knowledge/SQLiteKnowledgeBase.d.ts +29 -0
- package/dist/knowledge/SQLiteKnowledgeBase.js +203 -0
- package/dist/knowledge/SQLiteKnowledgeBase.js.map +1 -0
- package/dist/knowledge/TfidfIndex.d.ts +50 -0
- package/dist/knowledge/TfidfIndex.js +177 -0
- package/dist/knowledge/TfidfIndex.js.map +1 -0
- package/dist/knowledge/UbiquitousLanguageManager.d.ts +49 -0
- package/dist/knowledge/UbiquitousLanguageManager.js +133 -0
- package/dist/knowledge/UbiquitousLanguageManager.js.map +1 -0
- package/dist/memory/MemoryBrain.d.ts +146 -0
- package/dist/memory/MemoryBrain.js +679 -0
- package/dist/memory/MemoryBrain.js.map +1 -0
- package/dist/memory/MemoryFabric.d.ts +130 -0
- package/dist/memory/MemoryFabric.js +317 -0
- package/dist/memory/MemoryFabric.js.map +1 -0
- package/dist/memory/MemoryIntelligence.d.ts +42 -0
- package/dist/memory/MemoryIntelligence.js +215 -0
- package/dist/memory/MemoryIntelligence.js.map +1 -0
- package/dist/memory/MemoryLearning.d.ts +62 -0
- package/dist/memory/MemoryLearning.js +209 -0
- package/dist/memory/MemoryLearning.js.map +1 -0
- package/dist/memory/MemoryProviders.d.ts +165 -0
- package/dist/memory/MemoryProviders.js +940 -0
- package/dist/memory/MemoryProviders.js.map +1 -0
- package/dist/memory/MemoryReview.d.ts +65 -0
- package/dist/memory/MemoryReview.js +260 -0
- package/dist/memory/MemoryReview.js.map +1 -0
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/orchestration/EffectsWiring.d.ts +8 -0
- package/dist/orchestration/EffectsWiring.js +87 -0
- package/dist/orchestration/EffectsWiring.js.map +1 -0
- package/dist/orchestrator/OrchestratorDaemon.d.ts +44 -0
- package/dist/orchestrator/OrchestratorDaemon.js +150 -0
- package/dist/orchestrator/OrchestratorDaemon.js.map +1 -0
- package/dist/orchestrator/PolicyLoader.d.ts +80 -0
- package/dist/orchestrator/PolicyLoader.js +229 -0
- package/dist/orchestrator/PolicyLoader.js.map +1 -0
- package/dist/orchestrator/ReconciliationLoop.d.ts +71 -0
- package/dist/orchestrator/ReconciliationLoop.js +266 -0
- package/dist/orchestrator/ReconciliationLoop.js.map +1 -0
- package/dist/orchestrator/TrackerAdapter.d.ts +60 -0
- package/dist/orchestrator/TrackerAdapter.js +147 -0
- package/dist/orchestrator/TrackerAdapter.js.map +1 -0
- package/dist/orchestrator/WorkspaceManager.d.ts +66 -0
- package/dist/orchestrator/WorkspaceManager.js +257 -0
- package/dist/orchestrator/WorkspaceManager.js.map +1 -0
- package/dist/output/BrandThemeLoader.d.ts +54 -0
- package/dist/output/BrandThemeLoader.js +340 -0
- package/dist/output/BrandThemeLoader.js.map +1 -0
- package/dist/output/GovernanceDashboard.d.ts +59 -0
- package/dist/output/GovernanceDashboard.js +281 -0
- package/dist/output/GovernanceDashboard.js.map +1 -0
- package/dist/output/HTMLArtifactLayer.d.ts +97 -0
- package/dist/output/HTMLArtifactLayer.js +576 -0
- package/dist/output/HTMLArtifactLayer.js.map +1 -0
- package/dist/output/HTMLDocumentRenderer.d.ts +83 -0
- package/dist/output/HTMLDocumentRenderer.js +718 -0
- package/dist/output/HTMLDocumentRenderer.js.map +1 -0
- package/dist/output/UIPrototypeRenderer.d.ts +61 -0
- package/dist/output/UIPrototypeRenderer.js +500 -0
- package/dist/output/UIPrototypeRenderer.js.map +1 -0
- package/dist/output/index.d.ts +10 -0
- package/dist/output/index.js +8 -0
- package/dist/output/index.js.map +1 -0
- package/dist/prompts/PhasePromptRegistry.d.ts +53 -0
- package/dist/prompts/PhasePromptRegistry.js +517 -0
- package/dist/prompts/PhasePromptRegistry.js.map +1 -0
- package/dist/prompts/PromptOptimizer.d.ts +42 -0
- package/dist/prompts/PromptOptimizer.js +309 -0
- package/dist/prompts/PromptOptimizer.js.map +1 -0
- package/dist/prompts/VibeTemplateGallery.d.ts +25 -0
- package/dist/prompts/VibeTemplateGallery.js +295 -0
- package/dist/prompts/VibeTemplateGallery.js.map +1 -0
- package/dist/qa/BrowserDaemon.d.ts +23 -0
- package/dist/qa/BrowserDaemon.js +79 -0
- package/dist/qa/BrowserDaemon.js.map +1 -0
- package/dist/qa/E2ETestOrchestrator.d.ts +14 -0
- package/dist/qa/E2ETestOrchestrator.js +19 -0
- package/dist/qa/E2ETestOrchestrator.js.map +1 -0
- package/dist/review/CrossModelReviewer.d.ts +35 -0
- package/dist/review/CrossModelReviewer.js +75 -0
- package/dist/review/CrossModelReviewer.js.map +1 -0
- package/dist/review/ReviewAggregator.d.ts +13 -0
- package/dist/review/ReviewAggregator.js +28 -0
- package/dist/review/ReviewAggregator.js.map +1 -0
- package/dist/review/reviewCommands.d.ts +15 -0
- package/dist/review/reviewCommands.js +24 -0
- package/dist/review/reviewCommands.js.map +1 -0
- package/dist/routing/LocalModelProvider.d.ts +11 -0
- package/dist/routing/LocalModelProvider.js +21 -0
- package/dist/routing/LocalModelProvider.js.map +1 -0
- package/dist/routing/ModelRouter.d.ts +42 -0
- package/dist/routing/ModelRouter.js +94 -0
- package/dist/routing/ModelRouter.js.map +1 -0
- package/dist/routing/PromptCachePolicy.d.ts +37 -0
- package/dist/routing/PromptCachePolicy.js +97 -0
- package/dist/routing/PromptCachePolicy.js.map +1 -0
- package/dist/runtime/AiOsRuntime.d.ts +485 -0
- package/dist/runtime/AiOsRuntime.js +1846 -0
- package/dist/runtime/AiOsRuntime.js.map +1 -0
- package/dist/runtime/CostAnalyzer.d.ts +53 -0
- package/dist/runtime/CostAnalyzer.js +160 -0
- package/dist/runtime/CostAnalyzer.js.map +1 -0
- package/dist/runtime/CostOptimizer.d.ts +11 -0
- package/dist/runtime/CostOptimizer.js +21 -0
- package/dist/runtime/CostOptimizer.js.map +1 -0
- package/dist/runtime/ExecutionLedger.d.ts +46 -0
- package/dist/runtime/ExecutionLedger.js +71 -0
- package/dist/runtime/ExecutionLedger.js.map +1 -0
- package/dist/runtime/FinalReportGuard.d.ts +16 -0
- package/dist/runtime/FinalReportGuard.js +14 -0
- package/dist/runtime/FinalReportGuard.js.map +1 -0
- package/dist/runtime/ModelUsageLedger.d.ts +101 -0
- package/dist/runtime/ModelUsageLedger.js +296 -0
- package/dist/runtime/ModelUsageLedger.js.map +1 -0
- package/dist/runtime/RuntimeDoctor.d.ts +23 -0
- package/dist/runtime/RuntimeDoctor.js +151 -0
- package/dist/runtime/RuntimeDoctor.js.map +1 -0
- package/dist/runtime/RuntimeEvidenceLedger.d.ts +50 -0
- package/dist/runtime/RuntimeEvidenceLedger.js +89 -0
- package/dist/runtime/RuntimeEvidenceLedger.js.map +1 -0
- package/dist/runtime/SessionLedger.d.ts +53 -0
- package/dist/runtime/SessionLedger.js +104 -0
- package/dist/runtime/SessionLedger.js.map +1 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/setup/SetupVerification.d.ts +42 -0
- package/dist/setup/SetupVerification.js +180 -0
- package/dist/setup/SetupVerification.js.map +1 -0
- package/dist/setup/SetupWizard.d.ts +45 -0
- package/dist/setup/SetupWizard.js +216 -0
- package/dist/setup/SetupWizard.js.map +1 -0
- package/dist/shield/PolicyCompiler.d.ts +70 -0
- package/dist/shield/PolicyCompiler.js +540 -0
- package/dist/shield/PolicyCompiler.js.map +1 -0
- package/dist/shield/ProtectedPaths.d.ts +39 -0
- package/dist/shield/ProtectedPaths.js +179 -0
- package/dist/shield/ProtectedPaths.js.map +1 -0
- package/dist/shield/ShieldProtocol.d.ts +50 -0
- package/dist/shield/ShieldProtocol.js +103 -0
- package/dist/shield/ShieldProtocol.js.map +1 -0
- package/dist/skills/ExternalSkills.d.ts +3 -0
- package/dist/skills/ExternalSkills.js +27 -0
- package/dist/skills/ExternalSkills.js.map +1 -0
- package/dist/skills/GrillingSessionSkill.d.ts +65 -0
- package/dist/skills/GrillingSessionSkill.js +113 -0
- package/dist/skills/GrillingSessionSkill.js.map +1 -0
- package/dist/skills/GrillingTemplates.d.ts +7 -0
- package/dist/skills/GrillingTemplates.js +38 -0
- package/dist/skills/GrillingTemplates.js.map +1 -0
- package/dist/skills/RoleSkills.d.ts +20 -0
- package/dist/skills/RoleSkills.js +154 -0
- package/dist/skills/RoleSkills.js.map +1 -0
- package/dist/skills/SkillCatalog.d.ts +13 -0
- package/dist/skills/SkillCatalog.js +184 -0
- package/dist/skills/SkillCatalog.js.map +1 -0
- package/dist/skills/SkillDiscovery.d.ts +84 -0
- package/dist/skills/SkillDiscovery.js +402 -0
- package/dist/skills/SkillDiscovery.js.map +1 -0
- package/dist/skills/SkillDoctor.d.ts +37 -0
- package/dist/skills/SkillDoctor.js +267 -0
- package/dist/skills/SkillDoctor.js.map +1 -0
- package/dist/skills/SkillExecutor.d.ts +38 -0
- package/dist/skills/SkillExecutor.js +237 -0
- package/dist/skills/SkillExecutor.js.map +1 -0
- package/dist/skills/SkillFrontmatter.d.ts +28 -0
- package/dist/skills/SkillFrontmatter.js +152 -0
- package/dist/skills/SkillFrontmatter.js.map +1 -0
- package/dist/skills/SkillInstaller.d.ts +40 -0
- package/dist/skills/SkillInstaller.js +117 -0
- package/dist/skills/SkillInstaller.js.map +1 -0
- package/dist/skills/SkillMdStandard.d.ts +33 -0
- package/dist/skills/SkillMdStandard.js +88 -0
- package/dist/skills/SkillMdStandard.js.map +1 -0
- package/dist/skills/SkillRadar.d.ts +83 -0
- package/dist/skills/SkillRadar.js +404 -0
- package/dist/skills/SkillRadar.js.map +1 -0
- package/dist/skills/SkillRegistry.d.ts +112 -0
- package/dist/skills/SkillRegistry.js +161 -0
- package/dist/skills/SkillRegistry.js.map +1 -0
- package/dist/skills/SkillRepository.d.ts +71 -0
- package/dist/skills/SkillRepository.js +435 -0
- package/dist/skills/SkillRepository.js.map +1 -0
- package/dist/skills/TriggerEngine.d.ts +43 -0
- package/dist/skills/TriggerEngine.js +142 -0
- package/dist/skills/TriggerEngine.js.map +1 -0
- package/dist/skills/coreSkills.d.ts +6 -0
- package/dist/skills/coreSkills.js +41 -0
- package/dist/skills/coreSkills.js.map +1 -0
- package/dist/skills/index.d.ts +10 -0
- package/dist/skills/index.js +12 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/interop/GStackInterop.d.ts +15 -0
- package/dist/skills/interop/GStackInterop.js +34 -0
- package/dist/skills/interop/GStackInterop.js.map +1 -0
- package/dist/skills/interop/OMCInterop.d.ts +15 -0
- package/dist/skills/interop/OMCInterop.js +34 -0
- package/dist/skills/interop/OMCInterop.js.map +1 -0
- package/dist/skills/routing/SkillGate.d.ts +12 -0
- package/dist/skills/routing/SkillGate.js +117 -0
- package/dist/skills/routing/SkillGate.js.map +1 -0
- package/dist/skills/routing/SkillPlanner.d.ts +8 -0
- package/dist/skills/routing/SkillPlanner.js +179 -0
- package/dist/skills/routing/SkillPlanner.js.map +1 -0
- package/dist/skills/routing/SkillPolicy.d.ts +6 -0
- package/dist/skills/routing/SkillPolicy.js +336 -0
- package/dist/skills/routing/SkillPolicy.js.map +1 -0
- package/dist/skills/routing/SkillRoutingTypes.d.ts +89 -0
- package/dist/skills/routing/SkillRoutingTypes.js +2 -0
- package/dist/skills/routing/SkillRoutingTypes.js.map +1 -0
- package/dist/skills/routing/TaskIntentClassifier.d.ts +6 -0
- package/dist/skills/routing/TaskIntentClassifier.js +79 -0
- package/dist/skills/routing/TaskIntentClassifier.js.map +1 -0
- package/dist/skills/routing/index.d.ts +5 -0
- package/dist/skills/routing/index.js +6 -0
- package/dist/skills/routing/index.js.map +1 -0
- package/dist/tasks/IssueTriageFSM.d.ts +26 -0
- package/dist/tasks/IssueTriageFSM.js +107 -0
- package/dist/tasks/IssueTriageFSM.js.map +1 -0
- package/dist/tasks/TaskEngine.d.ts +97 -0
- package/dist/tasks/TaskEngine.js +289 -0
- package/dist/tasks/TaskEngine.js.map +1 -0
- package/dist/testing/DiffTestSelector.d.ts +22 -0
- package/dist/testing/DiffTestSelector.js +114 -0
- package/dist/testing/DiffTestSelector.js.map +1 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tools/CommandOutputCompressor.d.ts +28 -0
- package/dist/tools/CommandOutputCompressor.js +242 -0
- package/dist/tools/CommandOutputCompressor.js.map +1 -0
- package/dist/tools/CommandRunLedger.d.ts +77 -0
- package/dist/tools/CommandRunLedger.js +111 -0
- package/dist/tools/CommandRunLedger.js.map +1 -0
- package/dist/tools/RtkRuntime.d.ts +9 -0
- package/dist/tools/RtkRuntime.js +43 -0
- package/dist/tools/RtkRuntime.js.map +1 -0
- package/dist/tools/SafeCommandRunner.d.ts +16 -0
- package/dist/tools/SafeCommandRunner.js +83 -0
- package/dist/tools/SafeCommandRunner.js.map +1 -0
- package/dist/tools/ToolCapabilityRegistry.d.ts +51 -0
- package/dist/tools/ToolCapabilityRegistry.js +295 -0
- package/dist/tools/ToolCapabilityRegistry.js.map +1 -0
- package/dist/tools/ToolEvidenceGate.d.ts +39 -0
- package/dist/tools/ToolEvidenceGate.js +117 -0
- package/dist/tools/ToolEvidenceGate.js.map +1 -0
- package/dist/tools/ToolEvidenceStore.d.ts +58 -0
- package/dist/tools/ToolEvidenceStore.js +129 -0
- package/dist/tools/ToolEvidenceStore.js.map +1 -0
- package/dist/tools/ToolOrchestrator.d.ts +67 -0
- package/dist/tools/ToolOrchestrator.js +252 -0
- package/dist/tools/ToolOrchestrator.js.map +1 -0
- package/dist/tools/ToolPolicy.d.ts +33 -0
- package/dist/tools/ToolPolicy.js +172 -0
- package/dist/tools/ToolPolicy.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tui/TuiDashboard.d.ts +3 -0
- package/dist/tui/TuiDashboard.js +120 -0
- package/dist/tui/TuiDashboard.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/dist/workflow/AdaptiveWorkflowRouter.d.ts +38 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js +214 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js.map +1 -0
- package/dist/workflow/CommitDiscipline.d.ts +68 -0
- package/dist/workflow/CommitDiscipline.js +328 -0
- package/dist/workflow/CommitDiscipline.js.map +1 -0
- package/dist/workflow/ContextGovernance.d.ts +51 -0
- package/dist/workflow/ContextGovernance.js +233 -0
- package/dist/workflow/ContextGovernance.js.map +1 -0
- package/dist/workflow/CrossRepoOrchestrator.d.ts +92 -0
- package/dist/workflow/CrossRepoOrchestrator.js +408 -0
- package/dist/workflow/CrossRepoOrchestrator.js.map +1 -0
- package/dist/workflow/DiagnosticLoop.d.ts +40 -0
- package/dist/workflow/DiagnosticLoop.js +105 -0
- package/dist/workflow/DiagnosticLoop.js.map +1 -0
- package/dist/workflow/EngineeringStandards.d.ts +212 -0
- package/dist/workflow/EngineeringStandards.js +1113 -0
- package/dist/workflow/EngineeringStandards.js.map +1 -0
- package/dist/workflow/EvidenceStore.d.ts +20 -0
- package/dist/workflow/EvidenceStore.js +48 -0
- package/dist/workflow/EvidenceStore.js.map +1 -0
- package/dist/workflow/EvolutionShadowPromoter.d.ts +46 -0
- package/dist/workflow/EvolutionShadowPromoter.js +73 -0
- package/dist/workflow/EvolutionShadowPromoter.js.map +1 -0
- package/dist/workflow/GateCatalog.d.ts +63 -0
- package/dist/workflow/GateCatalog.js +268 -0
- package/dist/workflow/GateCatalog.js.map +1 -0
- package/dist/workflow/GovernanceLock.d.ts +35 -0
- package/dist/workflow/GovernanceLock.js +58 -0
- package/dist/workflow/GovernanceLock.js.map +1 -0
- package/dist/workflow/GovernanceRoi.d.ts +52 -0
- package/dist/workflow/GovernanceRoi.js +204 -0
- package/dist/workflow/GovernanceRoi.js.map +1 -0
- package/dist/workflow/GovernanceTemplatePacks.d.ts +24 -0
- package/dist/workflow/GovernanceTemplatePacks.js +2134 -0
- package/dist/workflow/GovernanceTemplatePacks.js.map +1 -0
- package/dist/workflow/GovernanceTemplates.d.ts +19 -0
- package/dist/workflow/GovernanceTemplates.js +1291 -0
- package/dist/workflow/GovernanceTemplates.js.map +1 -0
- package/dist/workflow/McpGovernance.d.ts +63 -0
- package/dist/workflow/McpGovernance.js +198 -0
- package/dist/workflow/McpGovernance.js.map +1 -0
- package/dist/workflow/OutOfScopeStore.d.ts +37 -0
- package/dist/workflow/OutOfScopeStore.js +164 -0
- package/dist/workflow/OutOfScopeStore.js.map +1 -0
- package/dist/workflow/PhaseMarkerTracker.d.ts +63 -0
- package/dist/workflow/PhaseMarkerTracker.js +291 -0
- package/dist/workflow/PhaseMarkerTracker.js.map +1 -0
- package/dist/workflow/ResourceGovernance.d.ts +120 -0
- package/dist/workflow/ResourceGovernance.js +531 -0
- package/dist/workflow/ResourceGovernance.js.map +1 -0
- package/dist/workflow/ReviewAnalyzer.d.ts +80 -0
- package/dist/workflow/ReviewAnalyzer.js +438 -0
- package/dist/workflow/ReviewAnalyzer.js.map +1 -0
- package/dist/workflow/ReviewStore.d.ts +36 -0
- package/dist/workflow/ReviewStore.js +42 -0
- package/dist/workflow/ReviewStore.js.map +1 -0
- package/dist/workflow/SecurityAudit.d.ts +27 -0
- package/dist/workflow/SecurityAudit.js +294 -0
- package/dist/workflow/SecurityAudit.js.map +1 -0
- package/dist/workflow/SessionCoordinator.d.ts +103 -0
- package/dist/workflow/SessionCoordinator.js +401 -0
- package/dist/workflow/SessionCoordinator.js.map +1 -0
- package/dist/workflow/SessionPreamble.d.ts +19 -0
- package/dist/workflow/SessionPreamble.js +130 -0
- package/dist/workflow/SessionPreamble.js.map +1 -0
- package/dist/workflow/SessionStateTracker.d.ts +74 -0
- package/dist/workflow/SessionStateTracker.js +270 -0
- package/dist/workflow/SessionStateTracker.js.map +1 -0
- package/dist/workflow/ShipPipeline.d.ts +30 -0
- package/dist/workflow/ShipPipeline.js +366 -0
- package/dist/workflow/ShipPipeline.js.map +1 -0
- package/dist/workflow/TaskArtifactScaffolder.d.ts +69 -0
- package/dist/workflow/TaskArtifactScaffolder.js +333 -0
- package/dist/workflow/TaskArtifactScaffolder.js.map +1 -0
- package/dist/workflow/TaskDependencyGraph.d.ts +73 -0
- package/dist/workflow/TaskDependencyGraph.js +245 -0
- package/dist/workflow/TaskDependencyGraph.js.map +1 -0
- package/dist/workflow/TaskLevelDetector.d.ts +41 -0
- package/dist/workflow/TaskLevelDetector.js +219 -0
- package/dist/workflow/TaskLevelDetector.js.map +1 -0
- package/dist/workflow/TaskMetricsStore.d.ts +49 -0
- package/dist/workflow/TaskMetricsStore.js +149 -0
- package/dist/workflow/TaskMetricsStore.js.map +1 -0
- package/dist/workflow/TaskScoreEngine.d.ts +42 -0
- package/dist/workflow/TaskScoreEngine.js +181 -0
- package/dist/workflow/TaskScoreEngine.js.map +1 -0
- package/dist/workflow/TddLoop.d.ts +49 -0
- package/dist/workflow/TddLoop.js +78 -0
- package/dist/workflow/TddLoop.js.map +1 -0
- package/dist/workflow/UpgradeManager.d.ts +178 -0
- package/dist/workflow/UpgradeManager.js +665 -0
- package/dist/workflow/UpgradeManager.js.map +1 -0
- package/dist/workflow/VerificationCommands.d.ts +36 -0
- package/dist/workflow/VerificationCommands.js +123 -0
- package/dist/workflow/VerificationCommands.js.map +1 -0
- package/dist/workflow/VerificationProfile.d.ts +67 -0
- package/dist/workflow/VerificationProfile.js +241 -0
- package/dist/workflow/VerificationProfile.js.map +1 -0
- package/dist/workflow/VerificationSchema.d.ts +46 -0
- package/dist/workflow/VerificationSchema.js +97 -0
- package/dist/workflow/VerificationSchema.js.map +1 -0
- package/dist/workflow/WorkflowArtifactWriter.d.ts +113 -0
- package/dist/workflow/WorkflowArtifactWriter.js +242 -0
- package/dist/workflow/WorkflowArtifactWriter.js.map +1 -0
- package/dist/workflow/WorkflowEngine.d.ts +83 -0
- package/dist/workflow/WorkflowEngine.js +183 -0
- package/dist/workflow/WorkflowEngine.js.map +1 -0
- package/dist/workflow/WorkflowGuidance.d.ts +30 -0
- package/dist/workflow/WorkflowGuidance.js +204 -0
- package/dist/workflow/WorkflowGuidance.js.map +1 -0
- package/dist/workflow/WorkflowOpenTasks.d.ts +16 -0
- package/dist/workflow/WorkflowOpenTasks.js +37 -0
- package/dist/workflow/WorkflowOpenTasks.js.map +1 -0
- package/dist/workflow/WorkflowOrchestrator.d.ts +59 -0
- package/dist/workflow/WorkflowOrchestrator.js +326 -0
- package/dist/workflow/WorkflowOrchestrator.js.map +1 -0
- package/dist/workflow/WorkflowTemplates.d.ts +38 -0
- package/dist/workflow/WorkflowTemplates.js +371 -0
- package/dist/workflow/WorkflowTemplates.js.map +1 -0
- package/dist/workflow/WorkspaceLifecycle.d.ts +71 -0
- package/dist/workflow/WorkspaceLifecycle.js +401 -0
- package/dist/workflow/WorkspaceLifecycle.js.map +1 -0
- package/dist/workflow/WorkspacePolicy.d.ts +46 -0
- package/dist/workflow/WorkspacePolicy.js +141 -0
- package/dist/workflow/WorkspacePolicy.js.map +1 -0
- package/dist/workflow/WorkspaceSafety.d.ts +9 -0
- package/dist/workflow/WorkspaceSafety.js +49 -0
- package/dist/workflow/WorkspaceSafety.js.map +1 -0
- package/dist/workflow/WorkspaceTopology.d.ts +58 -0
- package/dist/workflow/WorkspaceTopology.js +176 -0
- package/dist/workflow/WorkspaceTopology.js.map +1 -0
- package/dist/workflow/autofix/AutoFixEngine.d.ts +37 -0
- package/dist/workflow/autofix/AutoFixEngine.js +169 -0
- package/dist/workflow/autofix/AutoFixEngine.js.map +1 -0
- package/dist/workflow/autonomous/AutonomousDevLoop.d.ts +88 -0
- package/dist/workflow/autonomous/AutonomousDevLoop.js +381 -0
- package/dist/workflow/autonomous/AutonomousDevLoop.js.map +1 -0
- package/dist/workflow/autonomous/BackgroundHunter.d.ts +74 -0
- package/dist/workflow/autonomous/BackgroundHunter.js +220 -0
- package/dist/workflow/autonomous/BackgroundHunter.js.map +1 -0
- package/dist/workflow/autonomous/WorklogManager.d.ts +50 -0
- package/dist/workflow/autonomous/WorklogManager.js +264 -0
- package/dist/workflow/autonomous/WorklogManager.js.map +1 -0
- package/dist/workflow/autonomous/index.d.ts +3 -0
- package/dist/workflow/autonomous/index.js +5 -0
- package/dist/workflow/autonomous/index.js.map +1 -0
- package/dist/workflow/cognitive/AmbiguityScorer.d.ts +17 -0
- package/dist/workflow/cognitive/AmbiguityScorer.js +107 -0
- package/dist/workflow/cognitive/AmbiguityScorer.js.map +1 -0
- package/dist/workflow/cognitive/ConsensusPlanner.d.ts +26 -0
- package/dist/workflow/cognitive/ConsensusPlanner.js +141 -0
- package/dist/workflow/cognitive/ConsensusPlanner.js.map +1 -0
- package/dist/workflow/cognitive/SocraticQuestioner.d.ts +33 -0
- package/dist/workflow/cognitive/SocraticQuestioner.js +276 -0
- package/dist/workflow/cognitive/SocraticQuestioner.js.map +1 -0
- package/dist/workflow/evolution/LessonExtractor.d.ts +90 -0
- package/dist/workflow/evolution/LessonExtractor.js +317 -0
- package/dist/workflow/evolution/LessonExtractor.js.map +1 -0
- package/dist/workflow/evolution/SelfImproveEngine.d.ts +156 -0
- package/dist/workflow/evolution/SelfImproveEngine.js +361 -0
- package/dist/workflow/evolution/SelfImproveEngine.js.map +1 -0
- package/dist/workflow/execution/RalphEngine.d.ts +54 -0
- package/dist/workflow/execution/RalphEngine.js +145 -0
- package/dist/workflow/execution/RalphEngine.js.map +1 -0
- package/dist/workflow/execution/UltraworkEngine.d.ts +43 -0
- package/dist/workflow/execution/UltraworkEngine.js +135 -0
- package/dist/workflow/execution/UltraworkEngine.js.map +1 -0
- package/dist/workflow/gates/EnhancedGates.d.ts +74 -0
- package/dist/workflow/gates/EnhancedGates.js +653 -0
- package/dist/workflow/gates/EnhancedGates.js.map +1 -0
- package/dist/workflow/gates/GateSystem.d.ts +180 -0
- package/dist/workflow/gates/GateSystem.js +1279 -0
- package/dist/workflow/gates/GateSystem.js.map +1 -0
- package/dist/workflow/gates/MetaGovernanceGates.d.ts +70 -0
- package/dist/workflow/gates/MetaGovernanceGates.js +617 -0
- package/dist/workflow/gates/MetaGovernanceGates.js.map +1 -0
- package/dist/workflow/gates/VisualGate.d.ts +41 -0
- package/dist/workflow/gates/VisualGate.js +174 -0
- package/dist/workflow/gates/VisualGate.js.map +1 -0
- package/dist/workflow/index.d.ts +45 -0
- package/dist/workflow/index.js +47 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/qa/E2ETestRunner.d.ts +102 -0
- package/dist/workflow/qa/E2ETestRunner.js +227 -0
- package/dist/workflow/qa/E2ETestRunner.js.map +1 -0
- package/dist/workflow/quality/HonestDelivery.d.ts +19 -0
- package/dist/workflow/quality/HonestDelivery.js +77 -0
- package/dist/workflow/quality/HonestDelivery.js.map +1 -0
- package/dist/workflow/quality/KarpathyEvaluator.d.ts +18 -0
- package/dist/workflow/quality/KarpathyEvaluator.js +76 -0
- package/dist/workflow/quality/KarpathyEvaluator.js.map +1 -0
- package/dist/workflow/types.d.ts +151 -0
- package/dist/workflow/types.js +4 -0
- package/dist/workflow/types.js.map +1 -0
- package/dist/workflows/DAGBuilder.d.ts +52 -0
- package/dist/workflows/DAGBuilder.js +169 -0
- package/dist/workflows/DAGBuilder.js.map +1 -0
- package/dist/workflows/GateParser.d.ts +55 -0
- package/dist/workflows/GateParser.js +73 -0
- package/dist/workflows/GateParser.js.map +1 -0
- package/dist/workflows/WorkflowExecutor.d.ts +56 -0
- package/dist/workflows/WorkflowExecutor.js +143 -0
- package/dist/workflows/WorkflowExecutor.js.map +1 -0
- package/dist/workflows/WorkflowOrchestrator.d.ts +81 -0
- package/dist/workflows/WorkflowOrchestrator.js +337 -0
- package/dist/workflows/WorkflowOrchestrator.js.map +1 -0
- package/dist/workflows/index.d.ts +2 -0
- package/dist/workflows/index.js +5 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/presets.d.ts +34 -0
- package/dist/workflows/presets.js +224 -0
- package/dist/workflows/presets.js.map +1 -0
- package/docs/README.md +105 -0
- package/docs/guides/DEVELOPMENT_WORKFLOW.md +99 -0
- package/docs/guides/GETTING_STARTED.md +93 -0
- package/docs/guides/MEDICAL_AGENT_OPERATING_GUIDE.md +61 -0
- package/docs/guides/MEDICAL_RESEARCH_DELIVERY.md +217 -0
- package/docs/guides/MIGRATION.md +119 -0
- package/docs/reference/cli.md +2921 -0
- package/docs/start/README.md +79 -0
- package/docs/start/agent-governance-demo.md +107 -0
- package/docs/start/artifact-lifecycle.md +326 -0
- package/docs/start/quickstart.md +191 -0
- package/docs/start/workflow-upgrade.md +198 -0
- package/docs/workflow/GATES_AND_SCORE.md +89 -0
- package/docs/workflow/PROMPT_OPTIMIZATION.md +44 -0
- package/docs/workflow/README.md +123 -0
- package/docs/workflow/node-library.md +52 -0
- package/docs/workflow/templates/api-contract.md +29 -0
- package/docs/workflow/templates/architecture-review.md +23 -0
- package/docs/workflow/templates/db-change-plan.md +20 -0
- package/docs/workflow/templates/docs-impact.md +17 -0
- package/docs/workflow/templates/e2e-plan.md +20 -0
- package/docs/workflow/templates/explore.md +16 -0
- package/docs/workflow/templates/github-actions-scale-preflight.yml +32 -0
- package/docs/workflow/templates/mini-prd.md +16 -0
- package/docs/workflow/templates/plan.md +37 -0
- package/docs/workflow/templates/pre-push-scale-preflight.sh +8 -0
- package/docs/workflow/templates/product-smoke.md +61 -0
- package/docs/workflow/templates/reality-check.md +28 -0
- package/docs/workflow/templates/resource-cleanup.md +17 -0
- package/docs/workflow/templates/resource-impact.md +25 -0
- package/docs/workflow/templates/review.md +12 -0
- package/docs/workflow/templates/runtime.md +23 -0
- package/docs/workflow/templates/security-review.md +26 -0
- package/docs/workflow/templates/skill-evidence.md +33 -0
- package/docs/workflow/templates/skill-plan.md +39 -0
- package/docs/workflow/templates/spec.md +17 -0
- package/docs/workflow/templates/standards-impact.md +28 -0
- package/docs/workflow/templates/summary.md +16 -0
- package/docs/workflow/templates/tasks.md +8 -0
- package/docs/workflow/templates/ui-spec.md +29 -0
- package/docs/workflow/templates/verification.md +20 -0
- package/docs/workflow/templates/visual-review.md +20 -0
- package/docs/zh/quickstart.md +108 -0
- package/examples/demo-projects/agent-governance-demo/CONTEXT.md +14 -0
- package/examples/demo-projects/agent-governance-demo/README.md +48 -0
- package/examples/demo-projects/agent-governance-demo/docs/CONTEXT-MAP.md +14 -0
- package/examples/demo-projects/agent-governance-demo/package.json +22 -0
- package/examples/demo-projects/agent-governance-demo/src/oauth-state.ts +39 -0
- package/examples/demo-projects/agent-governance-demo/tests/oauth-state.test.ts +52 -0
- package/mcp-configs/_INDEX.md +55 -0
- package/mcp-configs/context7/config.json +9 -0
- package/mcp-configs/fetch/config.json +9 -0
- package/mcp-configs/filesystem/config.json +9 -0
- package/mcp-configs/github/config.json +11 -0
- package/mcp-configs/memory/config.json +9 -0
- package/mcp-configs/neon/config.json +11 -0
- package/mcp-configs/playwright/config.json +9 -0
- package/mcp-configs/postgres/config.json +11 -0
- package/mcp-configs/puppeteer/config.json +9 -0
- package/mcp-configs/sequential-thinking/config.json +9 -0
- package/package.json +113 -0
- package/scripts/workflow/lib/gbrain-runtime.mjs +185 -0
- package/scripts/workflow/lib/report-output.mjs +107 -0
- package/scripts/workflow/medscale-release-smoke.mjs +338 -0
- package/scripts/workflow/provider-rehearsal.mjs +597 -0
- package/scripts/workflow/setup-smoke.mjs +433 -0
- package/target-research-platform/bridge_runner.py +310 -0
- package/target-research-platform/config.yaml +148 -0
- package/target-research-platform/data/immune_infiltration/ACC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/BLCA.csv +201 -0
- package/target-research-platform/data/immune_infiltration/BRCA.csv +201 -0
- package/target-research-platform/data/immune_infiltration/CESC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/CHOL.csv +201 -0
- package/target-research-platform/data/immune_infiltration/COAD.csv +201 -0
- package/target-research-platform/data/immune_infiltration/DLBC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/ESCA.csv +201 -0
- package/target-research-platform/data/immune_infiltration/GBM.csv +201 -0
- package/target-research-platform/data/immune_infiltration/HNSC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/KICH.csv +201 -0
- package/target-research-platform/data/immune_infiltration/KIRC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/KIRP.csv +201 -0
- package/target-research-platform/data/immune_infiltration/LAML.csv +201 -0
- package/target-research-platform/data/immune_infiltration/LGG.csv +201 -0
- package/target-research-platform/data/immune_infiltration/LIHC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/LUAD.csv +201 -0
- package/target-research-platform/data/immune_infiltration/LUSC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/MESO.csv +201 -0
- package/target-research-platform/data/immune_infiltration/OV.csv +201 -0
- package/target-research-platform/data/immune_infiltration/PAAD.csv +201 -0
- package/target-research-platform/data/immune_infiltration/PCPG.csv +201 -0
- package/target-research-platform/data/immune_infiltration/PRAD.csv +201 -0
- package/target-research-platform/data/immune_infiltration/READ.csv +201 -0
- package/target-research-platform/data/immune_infiltration/SARC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/SKCM.csv +201 -0
- package/target-research-platform/data/immune_infiltration/STAD.csv +201 -0
- package/target-research-platform/data/immune_infiltration/TGCT.csv +201 -0
- package/target-research-platform/data/immune_infiltration/THCA.csv +201 -0
- package/target-research-platform/data/immune_infiltration/THYM.csv +201 -0
- package/target-research-platform/data/immune_infiltration/UCEC.csv +201 -0
- package/target-research-platform/data/immune_infiltration/UCS.csv +201 -0
- package/target-research-platform/data/immune_infiltration/UVM.csv +201 -0
- package/target-research-platform/docs/JSON_SCHEMA.md +352 -0
- package/target-research-platform/docs/PROGRESS_2026-06-09.md +140 -0
- package/target-research-platform/main.py +755 -0
- package/target-research-platform/pyproject.toml +54 -0
- package/target-research-platform/requirements.txt +9 -0
- package/target-research-platform/run_dashboard.py +5 -0
- package/target-research-platform/run_real_medical_workflow.py +28 -0
- package/target-research-platform/scripts/demo_report.py +481 -0
- package/target-research-platform/scripts/generate_evidence_package.py +75 -0
- package/target-research-platform/scripts/prepare_immune_data.py +386 -0
- package/target-research-platform/src/__init__.py +4 -0
- package/target-research-platform/src/analysis/__init__.py +3 -0
- package/target-research-platform/src/analysis/stage1_expression/__init__.py +12 -0
- package/target-research-platform/src/analysis/stage1_expression/immune_correlation.py +366 -0
- package/target-research-platform/src/analysis/stage1_expression/pipeline.py +579 -0
- package/target-research-platform/src/analysis/stage1_expression/survival_analysis.py +382 -0
- package/target-research-platform/src/analysis/stage2_screening/__init__.py +12 -0
- package/target-research-platform/src/analysis/stage2_screening/differential_expression.py +451 -0
- package/target-research-platform/src/analysis/stage2_screening/druggability_score.py +477 -0
- package/target-research-platform/src/analysis/stage2_screening/pipeline.py +822 -0
- package/target-research-platform/src/analysis/stage3_deep_research/__init__.py +12 -0
- package/target-research-platform/src/analysis/stage3_deep_research/competitive_landscape.py +479 -0
- package/target-research-platform/src/analysis/stage3_deep_research/pipeline.py +763 -0
- package/target-research-platform/src/analysis/stage3_deep_research/target_function.py +290 -0
- package/target-research-platform/src/analysis/stage4_business/__init__.py +12 -0
- package/target-research-platform/src/analysis/stage4_business/business_plan.py +816 -0
- package/target-research-platform/src/analysis/stage4_business/milestone_planner.py +844 -0
- package/target-research-platform/src/analysis/stage4_business/pipeline.py +284 -0
- package/target-research-platform/src/api_clients/__init__.py +29 -0
- package/target-research-platform/src/api_clients/aminer_client.py +163 -0
- package/target-research-platform/src/api_clients/base_client.py +186 -0
- package/target-research-platform/src/api_clients/clinicaltrials_client.py +411 -0
- package/target-research-platform/src/api_clients/geo_client.py +1420 -0
- package/target-research-platform/src/api_clients/gtex_client.py +209 -0
- package/target-research-platform/src/api_clients/hpa_client.py +170 -0
- package/target-research-platform/src/api_clients/immune_data_manager.py +247 -0
- package/target-research-platform/src/api_clients/openalex_client.py +86 -0
- package/target-research-platform/src/api_clients/opentargets_client.py +558 -0
- package/target-research-platform/src/api_clients/pubmed_client.py +361 -0
- package/target-research-platform/src/api_clients/tcga_client.py +712 -0
- package/target-research-platform/src/api_clients/timer_client.py +169 -0
- package/target-research-platform/src/dashboard/app.py +2283 -0
- package/target-research-platform/src/dashboard/deliverables.py +710 -0
- package/target-research-platform/src/dashboard/static/artifactPreview.js +96 -0
- package/target-research-platform/src/dashboard/static/index.html +1292 -0
- package/target-research-platform/src/dashboard/status_tracker.py +237 -0
- package/target-research-platform/src/output/__init__.py +42 -0
- package/target-research-platform/src/output/agent_llm_provider.py +171 -0
- package/target-research-platform/src/output/chart_generator.py +550 -0
- package/target-research-platform/src/output/data_exporter.py +215 -0
- package/target-research-platform/src/output/delivery_packager.py +791 -0
- package/target-research-platform/src/output/evidence_package.py +230 -0
- package/target-research-platform/src/output/journal_templates.py +193 -0
- package/target-research-platform/src/output/literature_enricher.py +395 -0
- package/target-research-platform/src/output/literature_reviewer.py +420 -0
- package/target-research-platform/src/output/manuscript_fact_checker.py +279 -0
- package/target-research-platform/src/output/manuscript_generator.py +1189 -0
- package/target-research-platform/src/output/manuscript_quality.py +401 -0
- package/target-research-platform/src/output/medical_skills_bridge.py +140 -0
- package/target-research-platform/src/output/report_generator.py +542 -0
- package/target-research-platform/src/output/usage_envelope.py +193 -0
- package/target-research-platform/src/utils/__init__.py +1 -0
- package/target-research-platform/src/utils/config.py +125 -0
- package/target-research-platform/src/utils/logger.py +71 -0
- package/target-research-platform/src/validators/__init__.py +13 -0
- package/target-research-platform/src/validators/cross_validator.py +394 -0
- package/target-research-platform/src/validators/data_provenance.py +298 -0
|
@@ -0,0 +1,1878 @@
|
|
|
1
|
+
// SCALE Engine - Phase-Aligned Commands (v0.10.0)
|
|
2
|
+
// 6 phase commands: DEFINE -> PLAN -> BUILD -> VERIFY -> REVIEW -> SHIP
|
|
3
|
+
// Integrates WorkflowEngine cognitive scaffolding and quality gates.
|
|
4
|
+
import { defineCommand } from 'citty';
|
|
5
|
+
// Engine singleton (reuse from cli.ts)
|
|
6
|
+
import { EventBus } from '../core/eventBus.js';
|
|
7
|
+
import { SQLiteArtifactStore } from '../artifact/sqliteStore.js';
|
|
8
|
+
import { FSM } from '../artifact/fsm.js';
|
|
9
|
+
import { registerAllFSMs } from '../artifact/fsmDefinitions.js';
|
|
10
|
+
import { CapabilityRegistry } from '../capabilities/CapabilityRegistry.js';
|
|
11
|
+
import { SkillRegistry } from '../skills/SkillRegistry.js';
|
|
12
|
+
import { registerCoreSkills } from '../skills/coreSkills.js';
|
|
13
|
+
import { registerExternalSkills } from '../skills/ExternalSkills.js';
|
|
14
|
+
import { createSkillPlan, evaluateSkillGate, loadSkillRoutingPolicy } from '../skills/routing/index.js';
|
|
15
|
+
import { inspectRequiredWorkflowSkills } from '../skills/SkillDoctor.js';
|
|
16
|
+
import { WorkflowEngine } from '../workflow/WorkflowEngine.js';
|
|
17
|
+
import { WorkflowArtifactWriter } from '../workflow/WorkflowArtifactWriter.js';
|
|
18
|
+
import { resolveVerificationTargets } from '../workflow/VerificationProfile.js';
|
|
19
|
+
import { EvidenceStore } from '../workflow/EvidenceStore.js';
|
|
20
|
+
import { ReviewStore } from '../workflow/ReviewStore.js';
|
|
21
|
+
import { TaskMetricsStore } from '../workflow/TaskMetricsStore.js';
|
|
22
|
+
import { appendVerificationArtifact, checkTaskArtifactCompleteness, scaffoldTaskArtifacts } from '../workflow/TaskArtifactScaffolder.js';
|
|
23
|
+
import { createWorkflowGuidance, renderWorkflowGuidance } from '../workflow/WorkflowGuidance.js';
|
|
24
|
+
import { blockingWorkflowOpenTasks, removeWorkflowOpenTask } from '../workflow/WorkflowOpenTasks.js';
|
|
25
|
+
import { doctorEngineeringStandards, settleEngineeringStandards } from '../workflow/EngineeringStandards.js';
|
|
26
|
+
import { analyzeReview, parseChangedFiles, shouldReviewFile, summarizeFindings } from '../workflow/ReviewAnalyzer.js';
|
|
27
|
+
import { inspectWorkspaceLifecycle } from '../workflow/WorkspaceLifecycle.js';
|
|
28
|
+
import { evaluateToolEvidenceGate } from '../tools/ToolEvidenceGate.js';
|
|
29
|
+
import { TaskLevelDetector } from '../workflow/TaskLevelDetector.js';
|
|
30
|
+
import { ToolEvidenceStore } from '../tools/ToolEvidenceStore.js';
|
|
31
|
+
import { ToolOrchestrator } from '../tools/ToolOrchestrator.js';
|
|
32
|
+
import { loadToolPolicy } from '../tools/ToolPolicy.js';
|
|
33
|
+
import { runSafeCommand } from '../tools/SafeCommandRunner.js';
|
|
34
|
+
import { join } from 'node:path';
|
|
35
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
36
|
+
import { HTMLDocumentRenderer } from '../output/HTMLDocumentRenderer.js';
|
|
37
|
+
import { SCALE_ENGINE_VERSION } from '../version.js';
|
|
38
|
+
import { optimizeCodingPrompt } from '../prompts/PromptOptimizer.js';
|
|
39
|
+
const SCALE_DIR = process.env.SCALE_DIR ?? '.scale';
|
|
40
|
+
const PROJECT_DIR = process.env.SCALE_PROJECT_DIR ?? process.cwd();
|
|
41
|
+
function validateVerificationEvidence(ids) {
|
|
42
|
+
const evidenceStore = new EvidenceStore(SCALE_DIR);
|
|
43
|
+
const missing = [];
|
|
44
|
+
const failed = [];
|
|
45
|
+
for (const id of ids ?? []) {
|
|
46
|
+
const record = evidenceStore.getGateResult(id);
|
|
47
|
+
if (!record) {
|
|
48
|
+
missing.push(id);
|
|
49
|
+
}
|
|
50
|
+
else if (!record.passed) {
|
|
51
|
+
failed.push(id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { ok: (ids?.length ?? 0) > 0 && missing.length === 0 && failed.length === 0, missing, failed };
|
|
55
|
+
}
|
|
56
|
+
function validateReviewEvidence(ids) {
|
|
57
|
+
const reviewStore = new ReviewStore(SCALE_DIR);
|
|
58
|
+
const missing = [];
|
|
59
|
+
const failed = [];
|
|
60
|
+
for (const id of ids ?? []) {
|
|
61
|
+
const record = reviewStore.getReview(id);
|
|
62
|
+
if (!record) {
|
|
63
|
+
missing.push(id);
|
|
64
|
+
}
|
|
65
|
+
else if (!record.passed) {
|
|
66
|
+
failed.push(id);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { ok: (ids?.length ?? 0) > 0 && missing.length === 0 && failed.length === 0, missing, failed };
|
|
70
|
+
}
|
|
71
|
+
function getValidatedReviewRecords(ids) {
|
|
72
|
+
const reviewStore = new ReviewStore(SCALE_DIR);
|
|
73
|
+
return (ids ?? [])
|
|
74
|
+
.map(id => reviewStore.getReview(id))
|
|
75
|
+
.filter((record) => Boolean(record?.passed));
|
|
76
|
+
}
|
|
77
|
+
function getVerificationEvidenceSummary(ids) {
|
|
78
|
+
const evidenceStore = new EvidenceStore(SCALE_DIR);
|
|
79
|
+
return (ids ?? [])
|
|
80
|
+
.map(id => evidenceStore.getGateResult(id))
|
|
81
|
+
.filter((record) => Boolean(record))
|
|
82
|
+
.map(record => ({ gate: record.gate, passed: record.passed }));
|
|
83
|
+
}
|
|
84
|
+
function getEngine() {
|
|
85
|
+
ensureDir(SCALE_DIR);
|
|
86
|
+
const eventBus = new EventBus({ eventsDir: join(SCALE_DIR, 'events') });
|
|
87
|
+
const store = new SQLiteArtifactStore(eventBus, {
|
|
88
|
+
dbPath: join(SCALE_DIR, 'scale.db'),
|
|
89
|
+
artifactsDir: join(SCALE_DIR, 'artifacts'),
|
|
90
|
+
});
|
|
91
|
+
const fsm = new FSM(store, eventBus);
|
|
92
|
+
registerAllFSMs(fsm);
|
|
93
|
+
// Initialize capability registry
|
|
94
|
+
const capabilityRegistry = new CapabilityRegistry(eventBus);
|
|
95
|
+
// Initialize skill registry
|
|
96
|
+
const skillRegistry = new SkillRegistry(eventBus);
|
|
97
|
+
registerCoreSkills(skillRegistry);
|
|
98
|
+
registerExternalSkills(skillRegistry, eventBus);
|
|
99
|
+
// Initialize workflow engine with cognitive scaffolding and quality gates.
|
|
100
|
+
const workflowEngine = new WorkflowEngine({
|
|
101
|
+
eventBus,
|
|
102
|
+
capabilityRegistry,
|
|
103
|
+
skillRegistry,
|
|
104
|
+
scaleDir: SCALE_DIR,
|
|
105
|
+
});
|
|
106
|
+
return { eventBus, store, fsm, workflowEngine, skillRegistry };
|
|
107
|
+
}
|
|
108
|
+
function ensureDir(dir) {
|
|
109
|
+
if (!existsSync(dir))
|
|
110
|
+
mkdirSync(dir, { recursive: true });
|
|
111
|
+
}
|
|
112
|
+
function isTruthyFlag(value) {
|
|
113
|
+
return value === true || value === '' || value === 'true' || value === '1';
|
|
114
|
+
}
|
|
115
|
+
function shouldSkipCommit(value) {
|
|
116
|
+
return isTruthyFlag(value) || process.argv.includes('--no-commit') || process.argv.includes('--skip-commit');
|
|
117
|
+
}
|
|
118
|
+
function normalizeGitPath(path) {
|
|
119
|
+
return path.replace(/\\/g, '/');
|
|
120
|
+
}
|
|
121
|
+
function normalizeWorkflowLevel(value) {
|
|
122
|
+
const normalized = String(value ?? 'M').trim().toUpperCase();
|
|
123
|
+
if (normalized === 'S' || normalized === 'M' || normalized === 'L' || normalized === 'CRITICAL') {
|
|
124
|
+
return normalized;
|
|
125
|
+
}
|
|
126
|
+
throw new Error(`Invalid workflow level "${String(value)}"; expected S, M, L, or CRITICAL.`);
|
|
127
|
+
}
|
|
128
|
+
function metricLevelFromPayload(payload) {
|
|
129
|
+
const level = normalizeWorkflowLevel(payload.workflowLevel ?? 'M');
|
|
130
|
+
return level === 'S' ? null : level;
|
|
131
|
+
}
|
|
132
|
+
function normalizeServices(value) {
|
|
133
|
+
if (!value)
|
|
134
|
+
return [];
|
|
135
|
+
return String(value)
|
|
136
|
+
.split(',')
|
|
137
|
+
.map(service => service.trim())
|
|
138
|
+
.filter(Boolean);
|
|
139
|
+
}
|
|
140
|
+
function isWorkflowGeneratedArtifact(path) {
|
|
141
|
+
return path.replace(/\\/g, '/').startsWith('docs/worklog/tasks/');
|
|
142
|
+
}
|
|
143
|
+
function checkCurrentTaskArtifacts(level) {
|
|
144
|
+
const state = new WorkflowArtifactWriter(SCALE_DIR).readCurrentState();
|
|
145
|
+
return checkTaskArtifactCompleteness({
|
|
146
|
+
projectDir: PROJECT_DIR,
|
|
147
|
+
artifactsDir: state?.artifactsDir,
|
|
148
|
+
level,
|
|
149
|
+
skillRequiredArtifacts: state?.requiredSkillArtifacts,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function planSkillsForTask(options) {
|
|
153
|
+
return createSkillPlan({
|
|
154
|
+
taskId: options.taskId,
|
|
155
|
+
taskName: options.taskName,
|
|
156
|
+
description: options.description,
|
|
157
|
+
level: options.level,
|
|
158
|
+
services: options.services ?? [],
|
|
159
|
+
files: options.files ?? [],
|
|
160
|
+
policy: loadSkillRoutingPolicy(PROJECT_DIR, SCALE_DIR),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function normalizeArtifactGateMode(value) {
|
|
164
|
+
if (value === undefined || value === null || value === '')
|
|
165
|
+
return undefined;
|
|
166
|
+
const normalized = String(value).trim().toLowerCase();
|
|
167
|
+
if (normalized === 'off' || normalized === 'warn' || normalized === 'block')
|
|
168
|
+
return normalized;
|
|
169
|
+
throw new Error(`Invalid artifact gate mode "${String(value)}"; expected off, warn, or block.`);
|
|
170
|
+
}
|
|
171
|
+
function artifactGateLevels(policy) {
|
|
172
|
+
return policy.artifactGateLevels?.length ? policy.artifactGateLevels : ['M', 'L', 'CRITICAL'];
|
|
173
|
+
}
|
|
174
|
+
function assumeVerificationArtifactWillBeWritten(check) {
|
|
175
|
+
if (!check.artifactsDir)
|
|
176
|
+
return check;
|
|
177
|
+
const missing = check.missing.filter(file => file !== 'verification.md');
|
|
178
|
+
const incomplete = check.incomplete.filter(item => item.file !== 'verification.md');
|
|
179
|
+
return {
|
|
180
|
+
...check,
|
|
181
|
+
missing,
|
|
182
|
+
incomplete,
|
|
183
|
+
complete: missing.length === 0 && incomplete.length === 0,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function evaluateArtifactGate(options) {
|
|
187
|
+
const mode = isTruthyFlag(options.requireArtifacts)
|
|
188
|
+
? 'block'
|
|
189
|
+
: normalizeArtifactGateMode(options.cliMode) ?? options.policy.artifactGate ?? 'warn';
|
|
190
|
+
const levels = artifactGateLevels(options.policy);
|
|
191
|
+
const applies = Boolean(options.level && levels.includes(options.level));
|
|
192
|
+
const checked = applies && mode !== 'off' && Boolean(options.check);
|
|
193
|
+
const complete = checked ? options.check?.complete : undefined;
|
|
194
|
+
return {
|
|
195
|
+
mode,
|
|
196
|
+
levels,
|
|
197
|
+
applies,
|
|
198
|
+
checked,
|
|
199
|
+
complete,
|
|
200
|
+
blocked: mode === 'block' && checked && complete === false,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function evaluateEngineeringStandardsGate(options) {
|
|
204
|
+
const mode = normalizeEngineeringStandardsGateMode(options.policy.engineeringStandardsGate);
|
|
205
|
+
if (mode === 'off') {
|
|
206
|
+
return {
|
|
207
|
+
mode,
|
|
208
|
+
checked: false,
|
|
209
|
+
blocked: false,
|
|
210
|
+
ok: true,
|
|
211
|
+
findings: [],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const settlement = options.settle && options.artifactsDir
|
|
215
|
+
? settleEngineeringStandards({
|
|
216
|
+
projectDir: PROJECT_DIR,
|
|
217
|
+
scaleDir: SCALE_DIR,
|
|
218
|
+
taskId: options.taskId,
|
|
219
|
+
artifactsDir: options.artifactsDir,
|
|
220
|
+
changedFiles: options.changedFiles,
|
|
221
|
+
})
|
|
222
|
+
: undefined;
|
|
223
|
+
const doctor = settlement?.doctor ?? doctorEngineeringStandards({
|
|
224
|
+
projectDir: PROJECT_DIR,
|
|
225
|
+
scaleDir: SCALE_DIR,
|
|
226
|
+
changedFiles: options.changedFiles,
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
mode,
|
|
230
|
+
checked: true,
|
|
231
|
+
blocked: mode === 'block' && !doctor.ok,
|
|
232
|
+
ok: doctor.ok,
|
|
233
|
+
findings: doctor.findings,
|
|
234
|
+
summary: doctor.scan.summary,
|
|
235
|
+
standardsImpactPath: settlement?.standardsImpactPath,
|
|
236
|
+
changedFiles: options.changedFiles,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function normalizeEngineeringStandardsGateMode(value) {
|
|
240
|
+
return value === 'off' || value === 'block' ? value : 'warn';
|
|
241
|
+
}
|
|
242
|
+
function normalizeToolGateMode(value) {
|
|
243
|
+
if (value === undefined || value === null || value === '')
|
|
244
|
+
return undefined;
|
|
245
|
+
const normalized = String(value).trim().toLowerCase();
|
|
246
|
+
if (normalized === 'warn')
|
|
247
|
+
return 'advisory';
|
|
248
|
+
if (normalized === 'off' || normalized === 'advisory' || normalized === 'evidence-required' || normalized === 'block')
|
|
249
|
+
return normalized;
|
|
250
|
+
throw new Error(`Invalid tool gate mode "${String(value)}"; expected off, advisory, evidence-required, or block.`);
|
|
251
|
+
}
|
|
252
|
+
function resolvePhaseToolGateMode(options) {
|
|
253
|
+
if (isTruthyFlag(options.requireEvidence))
|
|
254
|
+
return 'evidence-required';
|
|
255
|
+
const cliMode = normalizeToolGateMode(options.cliMode);
|
|
256
|
+
if (cliMode)
|
|
257
|
+
return cliMode;
|
|
258
|
+
return options.policy.mode === 'block' ? 'block' : 'off';
|
|
259
|
+
}
|
|
260
|
+
function evaluateTaskToolEvidenceGate(options) {
|
|
261
|
+
if (!options.level || !options.skillPlan)
|
|
262
|
+
return undefined;
|
|
263
|
+
const policy = loadToolPolicy(PROJECT_DIR, SCALE_DIR);
|
|
264
|
+
const mode = resolvePhaseToolGateMode({
|
|
265
|
+
cliMode: options.cliMode,
|
|
266
|
+
requireEvidence: options.requireEvidence,
|
|
267
|
+
policy,
|
|
268
|
+
});
|
|
269
|
+
const effectivePolicy = { ...policy, mode };
|
|
270
|
+
const evidenceStore = new ToolEvidenceStore({ projectDir: PROJECT_DIR, scaleDir: SCALE_DIR });
|
|
271
|
+
const plan = new ToolOrchestrator({
|
|
272
|
+
projectDir: PROJECT_DIR,
|
|
273
|
+
policy: effectivePolicy,
|
|
274
|
+
evidenceStore,
|
|
275
|
+
}).plan({ skillPlan: options.skillPlan });
|
|
276
|
+
return evaluateToolEvidenceGate({
|
|
277
|
+
projectDir: PROJECT_DIR,
|
|
278
|
+
level: options.level,
|
|
279
|
+
plan,
|
|
280
|
+
evidenceStore,
|
|
281
|
+
mode,
|
|
282
|
+
allowSkipped: isTruthyFlag(options.allowSkipped),
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
async function countChangedFiles(taskPayload) {
|
|
286
|
+
const filesInvolved = taskPayload.filesInvolved ?? [];
|
|
287
|
+
if (filesInvolved.length > 0)
|
|
288
|
+
return new Set(filesInvolved.map(normalizeGitPath)).size;
|
|
289
|
+
return (await detectTaskChangedFiles()).length;
|
|
290
|
+
}
|
|
291
|
+
async function detectTaskChangedFiles() {
|
|
292
|
+
try {
|
|
293
|
+
return (await getReviewableGitChanges())
|
|
294
|
+
.filter(file => !isWorkflowGeneratedArtifact(file.path))
|
|
295
|
+
.map(file => normalizeGitPath(file.path));
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
async function recordVerificationMetric(options) {
|
|
302
|
+
const level = metricLevelFromPayload(options.taskPayload);
|
|
303
|
+
if (!level)
|
|
304
|
+
return null;
|
|
305
|
+
const services = options.taskPayload.servicesTouched?.length
|
|
306
|
+
? options.taskPayload.servicesTouched
|
|
307
|
+
: options.serviceNames ?? [];
|
|
308
|
+
const metricsStore = new TaskMetricsStore(SCALE_DIR);
|
|
309
|
+
const artifactCheck = options.artifactCheck ?? checkCurrentTaskArtifacts(level);
|
|
310
|
+
const record = metricsStore.recordVerification({
|
|
311
|
+
taskId: options.taskId,
|
|
312
|
+
taskName: options.taskName,
|
|
313
|
+
level,
|
|
314
|
+
services,
|
|
315
|
+
filesChanged: await countChangedFiles(options.taskPayload),
|
|
316
|
+
passed: options.passed,
|
|
317
|
+
artifactComplete: artifactCheck.complete,
|
|
318
|
+
residualRisk: options.taskPayload.residualRisk,
|
|
319
|
+
finalGateStatus: options.finalGateStatus,
|
|
320
|
+
});
|
|
321
|
+
metricsStore.writeMarkdownReport(PROJECT_DIR);
|
|
322
|
+
return record;
|
|
323
|
+
}
|
|
324
|
+
// Helper: Generate spec markdown file
|
|
325
|
+
function generateSpecMarkdown(id, title, payload) {
|
|
326
|
+
return `# Spec: ${title}
|
|
327
|
+
|
|
328
|
+
**ID**: ${id}
|
|
329
|
+
**Status**: FROZEN
|
|
330
|
+
**Ambiguity Score**: ${payload.ambiguityScore ?? 0.15}
|
|
331
|
+
|
|
332
|
+
## What
|
|
333
|
+
${payload.what}
|
|
334
|
+
|
|
335
|
+
## Success Criteria
|
|
336
|
+
${payload.successCriteria.map(c => `- [ ] ${c}`).join('\n')}
|
|
337
|
+
|
|
338
|
+
## Out of Scope
|
|
339
|
+
${payload.outOfScope.map(o => `- ${o}`).join('\n') || '(none defined)'}
|
|
340
|
+
|
|
341
|
+
## Edge Cases
|
|
342
|
+
${payload.edgeCases.map(e => `- ${e}`).join('\n') || '(none defined)'}
|
|
343
|
+
|
|
344
|
+
## North Star
|
|
345
|
+
${payload.northStar || 'User value delivered'}
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
*Generated by SCALE Engine DEFINE phase*
|
|
349
|
+
`;
|
|
350
|
+
}
|
|
351
|
+
// Helper: Calculate ambiguity score
|
|
352
|
+
function calculateAmbiguityScore(description, successCriteria) {
|
|
353
|
+
let score = 0.2; // Base score (maximum threshold)
|
|
354
|
+
// Reduce score based on completeness
|
|
355
|
+
if (description.length > 50)
|
|
356
|
+
score -= 0.05;
|
|
357
|
+
if (successCriteria.length >= 2)
|
|
358
|
+
score -= 0.03;
|
|
359
|
+
if (successCriteria.length >= 3)
|
|
360
|
+
score -= 0.02;
|
|
361
|
+
return Math.max(0.05, score);
|
|
362
|
+
}
|
|
363
|
+
// DEFINE Phase - AmbiguityScorer + SocraticQuestioner + G1 gate
|
|
364
|
+
export const phaseDefine = defineCommand({
|
|
365
|
+
meta: { name: 'define', description: 'DEFINE: Create Spec with AmbiguityScorer + SocraticQuestioner (/spec)' },
|
|
366
|
+
args: {
|
|
367
|
+
title: { type: 'positional', required: true },
|
|
368
|
+
description: { type: 'string', alias: 'd' },
|
|
369
|
+
'success-criteria': { type: 'string', alias: 'c', description: 'Comma-separated criteria' },
|
|
370
|
+
// Socratic refinement answers (optional)
|
|
371
|
+
'goal': { type: 'string', description: 'Goal answer for Socratic refinement' },
|
|
372
|
+
'constraint': { type: 'string', description: 'Constraint answer for Socratic refinement' },
|
|
373
|
+
'acceptance': { type: 'string', description: 'Acceptance criteria answer for Socratic refinement' },
|
|
374
|
+
'context': { type: 'string', description: 'Context answer for Socratic refinement' },
|
|
375
|
+
'risk': { type: 'string', description: 'Risk answer for Socratic refinement' },
|
|
376
|
+
'priority': { type: 'string', description: 'Priority answer for Socratic refinement' },
|
|
377
|
+
format: { type: 'string', alias: 'f', description: 'Output format: html or md (default: html)' },
|
|
378
|
+
brand: { type: 'string', description: 'Brand theme for HTML output (vercel/stripe/notion/linear/github)' },
|
|
379
|
+
json: { type: 'boolean', default: false },
|
|
380
|
+
},
|
|
381
|
+
async run({ args }) {
|
|
382
|
+
const { store, fsm, workflowEngine } = getEngine();
|
|
383
|
+
const rawDesc = String(args.description ?? args.title);
|
|
384
|
+
// Parse success criteria
|
|
385
|
+
const successCriteria = args['success-criteria']
|
|
386
|
+
? args['success-criteria'].split(',').map(s => s.trim()).filter(s => s)
|
|
387
|
+
: ['Feature works as described', 'No regression in existing functionality'];
|
|
388
|
+
const promptOptimization = optimizeCodingPrompt({
|
|
389
|
+
rawPrompt: rawDesc,
|
|
390
|
+
title: String(args.title),
|
|
391
|
+
language: 'auto',
|
|
392
|
+
successCriteria,
|
|
393
|
+
});
|
|
394
|
+
const desc = promptOptimization.optimizedPrompt;
|
|
395
|
+
// === WorkflowEngine Integration ===
|
|
396
|
+
// Step 1: Explore with AmbiguityScorer + SocraticQuestioner
|
|
397
|
+
const exploreResult = await workflowEngine.explore(desc, { persistArtifact: false, runGate: false });
|
|
398
|
+
const ambiguityResult = workflowEngine.getAmbiguityScorer().analyzeRequirement(desc);
|
|
399
|
+
// Step 2: Check if requirement needs refinement.
|
|
400
|
+
if (ambiguityResult.blocked) {
|
|
401
|
+
console.error('\nRequirement ambiguity is too high (>40%); refine the requirement first.');
|
|
402
|
+
console.log('\n Refine the requirement by answering:');
|
|
403
|
+
console.log(' - What is the goal?');
|
|
404
|
+
console.log(' - What are the input/output boundaries?');
|
|
405
|
+
console.log(' - What are the acceptance criteria?\n');
|
|
406
|
+
process.exit(1);
|
|
407
|
+
}
|
|
408
|
+
// Step 3: Handle Socratic refinement if ambiguity > 20%
|
|
409
|
+
let refinedRequirement = desc;
|
|
410
|
+
let finalAmbiguityScore = ambiguityResult.totalScore;
|
|
411
|
+
if (ambiguityResult.requiresQuestioning && exploreResult.socraticSession) {
|
|
412
|
+
const session = exploreResult.socraticSession;
|
|
413
|
+
if (!args.json) {
|
|
414
|
+
console.log('\nRequirement ambiguity is >20%; starting Socratic refinement.');
|
|
415
|
+
console.log('\nSix-question refinement framework:');
|
|
416
|
+
console.log(workflowEngine.getSocraticQuestioner().formatSessionReport(session));
|
|
417
|
+
}
|
|
418
|
+
// Check if user provided answers via CLI args
|
|
419
|
+
const answers = [];
|
|
420
|
+
if (args.goal)
|
|
421
|
+
answers.push({ questionId: 'q-goal', answer: args.goal });
|
|
422
|
+
if (args.constraint)
|
|
423
|
+
answers.push({ questionId: 'q-constraint', answer: args.constraint });
|
|
424
|
+
if (args.acceptance)
|
|
425
|
+
answers.push({ questionId: 'q-acceptance', answer: args.acceptance });
|
|
426
|
+
if (args.context)
|
|
427
|
+
answers.push({ questionId: 'q-context', answer: args.context });
|
|
428
|
+
if (args.risk)
|
|
429
|
+
answers.push({ questionId: 'q-risk', answer: args.risk });
|
|
430
|
+
if (args.priority)
|
|
431
|
+
answers.push({ questionId: 'q-priority', answer: args.priority });
|
|
432
|
+
// If answers provided, process them
|
|
433
|
+
if (answers.length > 0) {
|
|
434
|
+
for (const { questionId, answer } of answers) {
|
|
435
|
+
workflowEngine.getSocraticQuestioner().recordAnswer(session.sessionId, questionId, answer);
|
|
436
|
+
}
|
|
437
|
+
const progress = workflowEngine.getSocraticQuestioner().evaluateProgress(session);
|
|
438
|
+
if (progress.refined) {
|
|
439
|
+
refinedRequirement = workflowEngine.getSocraticQuestioner().generateRefinedRequirement(session);
|
|
440
|
+
finalAmbiguityScore = progress.newAmbiguity;
|
|
441
|
+
if (!args.json) {
|
|
442
|
+
console.log('\nRequirement refined; ambiguity reduced to: ' + finalAmbiguityScore.toFixed(2));
|
|
443
|
+
console.log('\nRefined requirement:');
|
|
444
|
+
console.log(refinedRequirement);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
else if (!args.json) {
|
|
448
|
+
console.log('\nMore answers are needed to refine the requirement.');
|
|
449
|
+
console.log(' Current ambiguity: ' + progress.newAmbiguity.toFixed(2));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
else if (!args.json) {
|
|
453
|
+
console.log('\nYou can refine the requirement with:');
|
|
454
|
+
console.log(' --goal "goal description"');
|
|
455
|
+
console.log(' --constraint "constraints and boundaries"');
|
|
456
|
+
console.log(' --acceptance "acceptance criteria"');
|
|
457
|
+
console.log(' --context "context and dependencies"');
|
|
458
|
+
console.log(' --risk "risk scenarios"');
|
|
459
|
+
console.log(' --priority "priority order"\n');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const ambiguityScore = finalAmbiguityScore;
|
|
463
|
+
// Create Need artifact
|
|
464
|
+
const need = await store.create({
|
|
465
|
+
type: 'Need', title: args.title,
|
|
466
|
+
payload: { rawText: refinedRequirement },
|
|
467
|
+
initialStatus: 'DRAFT',
|
|
468
|
+
createdBy: { kind: 'human', userId: 'cli' },
|
|
469
|
+
});
|
|
470
|
+
// Create Spec artifact with proper payload (use refined requirement if available)
|
|
471
|
+
const specPayload = {
|
|
472
|
+
what: refinedRequirement,
|
|
473
|
+
successCriteria,
|
|
474
|
+
outOfScope: [],
|
|
475
|
+
edgeCases: [],
|
|
476
|
+
northStar: 'Deliver user value',
|
|
477
|
+
ambiguityScore,
|
|
478
|
+
};
|
|
479
|
+
const spec = await store.create({
|
|
480
|
+
type: 'Spec', title: args.title,
|
|
481
|
+
payload: specPayload,
|
|
482
|
+
parents: [need.id],
|
|
483
|
+
initialStatus: 'DRAFT',
|
|
484
|
+
createdBy: { kind: 'human', userId: 'cli' },
|
|
485
|
+
});
|
|
486
|
+
// Generate spec markdown file
|
|
487
|
+
const specsDir = join(SCALE_DIR, 'specs');
|
|
488
|
+
ensureDir(specsDir);
|
|
489
|
+
const specPath = join(specsDir, `${spec.id}.md`);
|
|
490
|
+
writeFileSync(specPath, generateSpecMarkdown(spec.id, args.title, specPayload));
|
|
491
|
+
// Generate spec HTML file (default format: html)
|
|
492
|
+
const outputFormat = args.format ?? 'md';
|
|
493
|
+
let specHtmlPath;
|
|
494
|
+
if (outputFormat === 'html') {
|
|
495
|
+
const renderer = new HTMLDocumentRenderer({
|
|
496
|
+
title: args.title,
|
|
497
|
+
brand: args.brand,
|
|
498
|
+
version: SCALE_ENGINE_VERSION,
|
|
499
|
+
status: 'FROZEN',
|
|
500
|
+
});
|
|
501
|
+
const html = renderer.renderSpec({
|
|
502
|
+
id: spec.id,
|
|
503
|
+
title: args.title,
|
|
504
|
+
what: refinedRequirement,
|
|
505
|
+
successCriteria,
|
|
506
|
+
outOfScope: specPayload.outOfScope,
|
|
507
|
+
edgeCases: specPayload.edgeCases,
|
|
508
|
+
northStar: specPayload.northStar,
|
|
509
|
+
ambiguityScore,
|
|
510
|
+
});
|
|
511
|
+
specHtmlPath = join(specsDir, `${spec.id}.html`);
|
|
512
|
+
renderer.writeToFile(html, specHtmlPath);
|
|
513
|
+
}
|
|
514
|
+
// FSM transitions: DRAFT -> REVIEWING -> FROZEN
|
|
515
|
+
// Phase 1: refine (DRAFT -> REVIEWING) - no guards
|
|
516
|
+
const refineResult = await fsm.canTransition(spec.id, 'refine');
|
|
517
|
+
if (!refineResult.allowed) {
|
|
518
|
+
if (!args.json) {
|
|
519
|
+
console.error('\nFSM transition blocked: DRAFT -> REVIEWING');
|
|
520
|
+
refineResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
521
|
+
}
|
|
522
|
+
process.exit(1);
|
|
523
|
+
}
|
|
524
|
+
await fsm.transition(spec.id, 'refine', { actor: { kind: 'system', component: 'phase-define' } });
|
|
525
|
+
// Phase 2: approve (REVIEWING -> FROZEN) - guards: ambiguityScore <= 0.2, has successCriteria
|
|
526
|
+
const approveResult = await fsm.canTransition(spec.id, 'approve');
|
|
527
|
+
if (!approveResult.allowed) {
|
|
528
|
+
if (!args.json) {
|
|
529
|
+
console.error('\nFSM transition blocked: REVIEWING -> FROZEN');
|
|
530
|
+
console.error(' Spec cannot be frozen due to:');
|
|
531
|
+
approveResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
532
|
+
console.error('\n Resolve issues before proceeding.');
|
|
533
|
+
}
|
|
534
|
+
process.exit(1);
|
|
535
|
+
}
|
|
536
|
+
await fsm.transition(spec.id, 'approve', { actor: { kind: 'system', component: 'phase-define' } });
|
|
537
|
+
if (!args.json) {
|
|
538
|
+
console.log(' FSM: DRAFT -> REVIEWING -> FROZEN ✓');
|
|
539
|
+
}
|
|
540
|
+
const result = { phase: 'DEFINE', spec, specPath, specHtmlPath, ambiguityScore, successCriteria, format: outputFormat, promptOptimization };
|
|
541
|
+
// Write explore artifact for Gate G1 verification
|
|
542
|
+
const artifactWriter = new WorkflowArtifactWriter(SCALE_DIR);
|
|
543
|
+
artifactWriter.writeExploreResult({
|
|
544
|
+
timestamp: new Date().toISOString(),
|
|
545
|
+
files: [specPath],
|
|
546
|
+
fileCount: 1,
|
|
547
|
+
mainContradiction: refinedRequirement !== desc ? 'requirement ambiguity resolved via Socratic refinement' : 'raw prompt optimized into structured execution prompt',
|
|
548
|
+
ambiguityScore,
|
|
549
|
+
socraticCompleted: !ambiguityResult.requiresQuestioning || (ambiguityResult.requiresQuestioning && !exploreResult.socraticSession),
|
|
550
|
+
});
|
|
551
|
+
if (args.json)
|
|
552
|
+
console.log(JSON.stringify(result, null, 2));
|
|
553
|
+
else {
|
|
554
|
+
console.log(`\nDEFINE: ${spec.id}`);
|
|
555
|
+
console.log(` Spec file: ${specPath}`);
|
|
556
|
+
if (specHtmlPath)
|
|
557
|
+
console.log(` HTML file: ${specHtmlPath}`);
|
|
558
|
+
console.log(` Ambiguity score: ${ambiguityScore.toFixed(2)}`);
|
|
559
|
+
console.log(` Success criteria: ${successCriteria.length}`);
|
|
560
|
+
console.log(`\n Next: scale plan ${spec.id}\n`);
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
// Helper: Generate plan markdown file
|
|
565
|
+
function generatePlanMarkdown(id, specId, payload) {
|
|
566
|
+
return `# Plan: ${id}
|
|
567
|
+
|
|
568
|
+
**Spec**: ${specId}
|
|
569
|
+
**Status**: APPROVED
|
|
570
|
+
|
|
571
|
+
## Approach
|
|
572
|
+
${payload.approach}
|
|
573
|
+
|
|
574
|
+
## Tech Choices
|
|
575
|
+
${payload.techChoices.map(t => `- **${t.decision}**: ${t.rationale}`).join('\n') || '(to be defined)'}
|
|
576
|
+
|
|
577
|
+
## Modules
|
|
578
|
+
${payload.modules.map(m => `- ${m.action} \`${m.path}\`: ${m.reason}`).join('\n') || '(to be defined)'}
|
|
579
|
+
|
|
580
|
+
## Rollback Strategy
|
|
581
|
+
${payload.rollbackStrategy}
|
|
582
|
+
|
|
583
|
+
## Estimated Complexity
|
|
584
|
+
${payload.estimatedComplexity ?? 5}/10
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
*Generated by SCALE Engine PLAN phase*
|
|
588
|
+
`;
|
|
589
|
+
}
|
|
590
|
+
// PLAN Phase - ConsensusPlanner + G2 gate
|
|
591
|
+
export const phasePlan = defineCommand({
|
|
592
|
+
meta: { name: 'plan', description: 'PLAN: Create Plan with ConsensusPlanner (/plan)' },
|
|
593
|
+
args: {
|
|
594
|
+
'spec-id': { type: 'positional', required: true },
|
|
595
|
+
approach: { type: 'string', alias: 'a', description: 'Implementation approach' },
|
|
596
|
+
'rollback': { type: 'string', alias: 'r', description: 'Rollback strategy (required for FSM)' },
|
|
597
|
+
format: { type: 'string', alias: 'f', description: 'Output format: html or md (default: html)' },
|
|
598
|
+
brand: { type: 'string', description: 'Brand theme for HTML output (vercel/stripe/notion/linear/github)' },
|
|
599
|
+
json: { type: 'boolean', default: false },
|
|
600
|
+
},
|
|
601
|
+
async run({ args }) {
|
|
602
|
+
const { store, fsm, workflowEngine } = getEngine();
|
|
603
|
+
// Validate spec exists
|
|
604
|
+
const spec = await store.get(args['spec-id']);
|
|
605
|
+
if (!spec || spec.type !== 'Spec') {
|
|
606
|
+
console.error(`\nSpec not found: ${args['spec-id']}\n`);
|
|
607
|
+
process.exit(1);
|
|
608
|
+
}
|
|
609
|
+
// === WorkflowEngine Integration ===
|
|
610
|
+
// Step 1: Run ConsensusPlanner (Planner -> Architect -> Critic).
|
|
611
|
+
const specDesc = spec.payload.what;
|
|
612
|
+
const consensusResult = await workflowEngine.plan(specDesc, { persistArtifact: false, runGate: false });
|
|
613
|
+
// Step 2: Display RALPLAN-DR output
|
|
614
|
+
if (!args.json) {
|
|
615
|
+
console.log('\nConsensus Planning Result:');
|
|
616
|
+
console.log(workflowEngine.getConsensusPlanner().formatReport(consensusResult));
|
|
617
|
+
}
|
|
618
|
+
// Default rollback strategy (FSM guard requires this)
|
|
619
|
+
const rollbackStrategy = args.rollback ?? consensusResult.preMortem.mitigations.join('\n') ?? 'Revert git commits';
|
|
620
|
+
const approach = args.approach ?? consensusResult.viableOptions.find((o) => o.selected)?.description ?? 'Standard implementation';
|
|
621
|
+
// Create PlanPayload with rollback strategy
|
|
622
|
+
const planPayload = {
|
|
623
|
+
approach,
|
|
624
|
+
techChoices: [],
|
|
625
|
+
modules: [],
|
|
626
|
+
rollbackStrategy,
|
|
627
|
+
estimatedComplexity: 5,
|
|
628
|
+
};
|
|
629
|
+
const plan = await store.create({
|
|
630
|
+
type: 'Plan', title: `Plan for ${spec.title}`,
|
|
631
|
+
payload: planPayload,
|
|
632
|
+
parents: [args['spec-id']],
|
|
633
|
+
initialStatus: 'DRAFT',
|
|
634
|
+
createdBy: { kind: 'human', userId: 'cli' },
|
|
635
|
+
});
|
|
636
|
+
// Generate plan markdown file
|
|
637
|
+
const plansDir = join(SCALE_DIR, 'plans');
|
|
638
|
+
ensureDir(plansDir);
|
|
639
|
+
const planPath = join(plansDir, `${plan.id}.md`);
|
|
640
|
+
writeFileSync(planPath, generatePlanMarkdown(plan.id, args['spec-id'], planPayload));
|
|
641
|
+
// Generate plan HTML file (default format: html)
|
|
642
|
+
const planOutputFormat = args.format ?? 'md';
|
|
643
|
+
let planHtmlPath;
|
|
644
|
+
if (planOutputFormat === 'html') {
|
|
645
|
+
const planRenderer = new HTMLDocumentRenderer({
|
|
646
|
+
title: `Plan ${plan.id}`,
|
|
647
|
+
brand: args.brand,
|
|
648
|
+
version: SCALE_ENGINE_VERSION,
|
|
649
|
+
status: 'APPROVED',
|
|
650
|
+
});
|
|
651
|
+
const planHtml = planRenderer.renderPlan({
|
|
652
|
+
id: plan.id,
|
|
653
|
+
specId: args['spec-id'],
|
|
654
|
+
approach: planPayload.approach,
|
|
655
|
+
techChoices: planPayload.techChoices,
|
|
656
|
+
modules: planPayload.modules,
|
|
657
|
+
rollbackStrategy: planPayload.rollbackStrategy,
|
|
658
|
+
estimatedComplexity: planPayload.estimatedComplexity,
|
|
659
|
+
});
|
|
660
|
+
planHtmlPath = join(plansDir, `${plan.id}.html`);
|
|
661
|
+
planRenderer.writeToFile(planHtml, planHtmlPath);
|
|
662
|
+
}
|
|
663
|
+
// Write plan artifact for Gate G2 verification
|
|
664
|
+
const artifactWriter = new WorkflowArtifactWriter(SCALE_DIR);
|
|
665
|
+
artifactWriter.writePlanResult({
|
|
666
|
+
timestamp: new Date().toISOString(),
|
|
667
|
+
planId: plan.id,
|
|
668
|
+
specId: args['spec-id'],
|
|
669
|
+
hasBoundaryAnalysis: consensusResult.viableOptions.length > 1,
|
|
670
|
+
hasExceptionHandling: consensusResult.preMortem.rootCauses.length > 0,
|
|
671
|
+
hasRollbackStrategy: !!rollbackStrategy,
|
|
672
|
+
modules: planPayload.modules.map(m => m.path),
|
|
673
|
+
consensusRounds: consensusResult.iterationCount,
|
|
674
|
+
verdict: consensusResult.verdict,
|
|
675
|
+
});
|
|
676
|
+
// FSM transition: DRAFT -> APPROVED (requires rollbackStrategy guard)
|
|
677
|
+
const reviewResult = await fsm.canTransition(plan.id, 'review');
|
|
678
|
+
if (!reviewResult.allowed) {
|
|
679
|
+
if (!args.json) {
|
|
680
|
+
console.error('\nFSM transition blocked: DRAFT -> APPROVED');
|
|
681
|
+
console.error(' Plan cannot be approved due to:');
|
|
682
|
+
reviewResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
683
|
+
console.error('\n Provide rollback strategy: --rollback "Revert strategy description"');
|
|
684
|
+
}
|
|
685
|
+
process.exit(1);
|
|
686
|
+
}
|
|
687
|
+
await fsm.transition(plan.id, 'review', { actor: { kind: 'system', component: 'phase-plan' } });
|
|
688
|
+
if (!args.json) {
|
|
689
|
+
console.log(' FSM: DRAFT -> APPROVED ✓');
|
|
690
|
+
}
|
|
691
|
+
const result = { phase: 'PLAN', plan, planPath, planHtmlPath, rollbackStrategy, format: planOutputFormat };
|
|
692
|
+
if (args.json)
|
|
693
|
+
console.log(JSON.stringify(result, null, 2));
|
|
694
|
+
else {
|
|
695
|
+
console.log(`\nPLAN: ${plan.id}`);
|
|
696
|
+
console.log(` Plan file: ${planPath}`);
|
|
697
|
+
if (planHtmlPath)
|
|
698
|
+
console.log(` HTML file: ${planHtmlPath}`);
|
|
699
|
+
console.log(` Rollback: ${rollbackStrategy}`);
|
|
700
|
+
console.log(`\n Next: scale build ${plan.id}\n`);
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
});
|
|
704
|
+
// BUILD Phase
|
|
705
|
+
export const phaseBuild = defineCommand({
|
|
706
|
+
meta: { name: 'build', description: 'BUILD: Create Task (/build)' },
|
|
707
|
+
args: {
|
|
708
|
+
'plan-id': { type: 'positional', required: true },
|
|
709
|
+
description: { type: 'string', alias: 'd', description: 'Task description' },
|
|
710
|
+
level: { type: 'string', default: '', description: 'Workflow task level: S, M, L, or CRITICAL (auto-detected if omitted)' },
|
|
711
|
+
service: { type: 'string', description: 'Comma-separated service names touched by this task' },
|
|
712
|
+
'residual-risk': { type: 'string', description: 'Known residual risk statement for metrics' },
|
|
713
|
+
json: { type: 'boolean', default: false },
|
|
714
|
+
},
|
|
715
|
+
async run({ args }) {
|
|
716
|
+
const { store, fsm } = getEngine();
|
|
717
|
+
// Validate plan exists
|
|
718
|
+
const plan = await store.get(args['plan-id']);
|
|
719
|
+
if (!plan || plan.type !== 'Plan') {
|
|
720
|
+
console.error(`\nPlan not found: ${args['plan-id']}\n`);
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
let workflowLevel;
|
|
724
|
+
if (args.level) {
|
|
725
|
+
try {
|
|
726
|
+
workflowLevel = normalizeWorkflowLevel(args.level);
|
|
727
|
+
}
|
|
728
|
+
catch (e) {
|
|
729
|
+
console.error(`\n${e.message}\n`);
|
|
730
|
+
process.exit(1);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
// Auto-detect task level from git diff
|
|
735
|
+
const detector = new TaskLevelDetector();
|
|
736
|
+
const detection = await detector.detectFromGitDiff();
|
|
737
|
+
workflowLevel = detection.level;
|
|
738
|
+
if (!args.json) {
|
|
739
|
+
console.log(`\nAuto-detected level: ${detection.level} (confidence: ${detection.confidence})`);
|
|
740
|
+
for (const reason of detection.reasons) {
|
|
741
|
+
console.log(` - ${reason}`);
|
|
742
|
+
}
|
|
743
|
+
console.log();
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
// Create TaskPayload
|
|
747
|
+
const taskPayload = {
|
|
748
|
+
description: args.description ?? `Implement ${plan.title}`,
|
|
749
|
+
workflowLevel,
|
|
750
|
+
servicesTouched: normalizeServices(args.service),
|
|
751
|
+
residualRisk: args['residual-risk'],
|
|
752
|
+
filesInvolved: [],
|
|
753
|
+
dependsOn: [],
|
|
754
|
+
requiredRole: 'implementer',
|
|
755
|
+
requiredCapabilities: ['code-generation', 'file-editing'],
|
|
756
|
+
// Initialize quality metrics (FSM guards require these for completion)
|
|
757
|
+
buildStatus: 'pending',
|
|
758
|
+
lintStatus: 'pending',
|
|
759
|
+
testPassed: undefined,
|
|
760
|
+
testCoverage: undefined,
|
|
761
|
+
agentBrief: {
|
|
762
|
+
category: 'enhancement',
|
|
763
|
+
summary: args.description ?? `Implement ${plan.title}`,
|
|
764
|
+
currentBehavior: 'Feature not yet implemented',
|
|
765
|
+
desiredBehavior: `Implement: ${plan.title}`,
|
|
766
|
+
keyInterfaces: [],
|
|
767
|
+
acceptanceCriteria: [],
|
|
768
|
+
outOfScope: [],
|
|
769
|
+
},
|
|
770
|
+
};
|
|
771
|
+
const taskTitle = `Task for ${plan.title}`;
|
|
772
|
+
const task = await store.create({
|
|
773
|
+
type: 'Task', title: taskTitle,
|
|
774
|
+
payload: taskPayload,
|
|
775
|
+
parents: [args['plan-id']],
|
|
776
|
+
initialStatus: 'PENDING',
|
|
777
|
+
createdBy: { kind: 'human', userId: 'cli' },
|
|
778
|
+
});
|
|
779
|
+
const skillPlan = planSkillsForTask({
|
|
780
|
+
taskId: task.id,
|
|
781
|
+
taskName: taskTitle,
|
|
782
|
+
description: taskPayload.description,
|
|
783
|
+
level: workflowLevel,
|
|
784
|
+
services: taskPayload.servicesTouched,
|
|
785
|
+
files: taskPayload.filesInvolved,
|
|
786
|
+
});
|
|
787
|
+
const taskPayloadWithSkills = {
|
|
788
|
+
...taskPayload,
|
|
789
|
+
skillIntents: skillPlan.intents.map(intent => intent.domain),
|
|
790
|
+
skillRoutingMode: skillPlan.mode,
|
|
791
|
+
skillPlanRequired: skillPlan.required,
|
|
792
|
+
requiredSkills: skillPlan.requiredSkills,
|
|
793
|
+
recommendedSkills: skillPlan.recommendedSkills,
|
|
794
|
+
requiredSkillArtifacts: skillPlan.requiredArtifacts,
|
|
795
|
+
requiredSkillVerification: skillPlan.requiredVerification,
|
|
796
|
+
};
|
|
797
|
+
await store.update(task.id, { payload: taskPayloadWithSkills });
|
|
798
|
+
let taskArtifacts;
|
|
799
|
+
if (workflowLevel !== 'S') {
|
|
800
|
+
taskArtifacts = scaffoldTaskArtifacts({
|
|
801
|
+
projectDir: PROJECT_DIR,
|
|
802
|
+
taskId: task.id,
|
|
803
|
+
taskName: task.title,
|
|
804
|
+
description: taskPayloadWithSkills.description,
|
|
805
|
+
level: workflowLevel,
|
|
806
|
+
services: taskPayloadWithSkills.servicesTouched,
|
|
807
|
+
skillPlan,
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
const workflowGuidance = createWorkflowGuidance({
|
|
811
|
+
taskId: task.id,
|
|
812
|
+
description: taskPayloadWithSkills.description,
|
|
813
|
+
level: workflowLevel,
|
|
814
|
+
artifactDir: taskArtifacts?.relativeDir,
|
|
815
|
+
files: taskPayloadWithSkills.filesInvolved,
|
|
816
|
+
skillIntents: taskPayloadWithSkills.skillIntents,
|
|
817
|
+
requiredSkillVerification: taskPayloadWithSkills.requiredSkillVerification,
|
|
818
|
+
});
|
|
819
|
+
new WorkflowArtifactWriter(SCALE_DIR).updateCurrentState({
|
|
820
|
+
taskId: task.id,
|
|
821
|
+
level: workflowLevel,
|
|
822
|
+
phase: 'build',
|
|
823
|
+
lastTaskId: task.id,
|
|
824
|
+
artifactsDir: taskArtifacts?.relativeDir,
|
|
825
|
+
skillIntents: skillPlan.intents.map(intent => intent.domain),
|
|
826
|
+
skillRoutingMode: skillPlan.mode,
|
|
827
|
+
skillPlanRequired: skillPlan.required,
|
|
828
|
+
skillPlanPath: taskArtifacts?.relativeDir ? `${taskArtifacts.relativeDir}/skill-plan.md` : undefined,
|
|
829
|
+
requiredSkills: skillPlan.requiredSkills,
|
|
830
|
+
recommendedSkills: skillPlan.recommendedSkills,
|
|
831
|
+
requiredSkillArtifacts: skillPlan.requiredArtifacts,
|
|
832
|
+
requiredSkillVerification: skillPlan.requiredVerification,
|
|
833
|
+
openTasks: workflowGuidance.items.filter(item => item.required).map(item => item.command),
|
|
834
|
+
});
|
|
835
|
+
// FSM transitions: PENDING -> READY -> RUNNING
|
|
836
|
+
// Phase 1: schedule (PENDING -> READY) - no guards
|
|
837
|
+
const scheduleResult = await fsm.canTransition(task.id, 'schedule');
|
|
838
|
+
if (!scheduleResult.allowed) {
|
|
839
|
+
if (!args.json) {
|
|
840
|
+
console.error('\nFSM transition blocked: PENDING -> READY');
|
|
841
|
+
scheduleResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
842
|
+
}
|
|
843
|
+
process.exit(1);
|
|
844
|
+
}
|
|
845
|
+
await fsm.transition(task.id, 'schedule', { actor: { kind: 'system', component: 'phase-build' } });
|
|
846
|
+
// Phase 2: start (READY -> RUNNING) - no guards
|
|
847
|
+
await fsm.transition(task.id, 'start', { actor: { kind: 'human', userId: 'cli' } });
|
|
848
|
+
if (!args.json) {
|
|
849
|
+
console.log(' FSM: PENDING -> READY -> RUNNING ✓');
|
|
850
|
+
}
|
|
851
|
+
// Update Plan status to IMPLEMENTING
|
|
852
|
+
const implResult = await fsm.canTransition(args['plan-id'], 'implement');
|
|
853
|
+
if (implResult.allowed) {
|
|
854
|
+
await fsm.transition(args['plan-id'], 'implement', { actor: { kind: 'system', component: 'phase-build' } });
|
|
855
|
+
}
|
|
856
|
+
const result = { phase: 'BUILD', task: { ...task, payload: taskPayloadWithSkills }, status: 'RUNNING', artifactDir: taskArtifacts?.relativeDir, artifactFiles: taskArtifacts?.created ?? [], skillPlan, workflowGuidance };
|
|
857
|
+
if (args.json)
|
|
858
|
+
console.log(JSON.stringify(result, null, 2));
|
|
859
|
+
else {
|
|
860
|
+
console.log(`\nBUILD: ${task.id}`);
|
|
861
|
+
console.log(` Status: RUNNING (ready to implement)`);
|
|
862
|
+
console.log(` Description: ${taskPayloadWithSkills.description}`);
|
|
863
|
+
if (skillPlan.intents.length)
|
|
864
|
+
console.log(` Skill intents: ${skillPlan.intents.map(intent => intent.domain).join(', ')}`);
|
|
865
|
+
if (skillPlan.requiredSkills.length)
|
|
866
|
+
console.log(` Required skills: ${skillPlan.requiredSkills.join(', ')}`);
|
|
867
|
+
if (skillPlan.recommendedSkills.length)
|
|
868
|
+
console.log(` Recommended skills: ${skillPlan.recommendedSkills.join(', ')}`);
|
|
869
|
+
if (taskArtifacts?.relativeDir)
|
|
870
|
+
console.log(` Artifacts: ${taskArtifacts.relativeDir}`);
|
|
871
|
+
console.log(`\n${renderWorkflowGuidance(workflowGuidance)}`);
|
|
872
|
+
console.log('');
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
});
|
|
876
|
+
// Helper: Run command and capture result (from verify-task)
|
|
877
|
+
async function runVerificationCmd(cmd) {
|
|
878
|
+
try {
|
|
879
|
+
const result = await runSafeCommand(cmd);
|
|
880
|
+
return { exitCode: result.exitCode, output: [result.stdout, result.stderr].filter(Boolean).join('\n') };
|
|
881
|
+
}
|
|
882
|
+
catch (error) {
|
|
883
|
+
return { exitCode: 1, output: error instanceof Error ? error.message : String(error) };
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
// VERIFY Phase - GateSystem quality gates
|
|
887
|
+
export const phaseVerify = defineCommand({
|
|
888
|
+
meta: { name: 'verify', description: 'VERIFY: Run Gates G3-G7 (/test)' },
|
|
889
|
+
args: {
|
|
890
|
+
'task-id': { type: 'positional', required: true },
|
|
891
|
+
'build-cmd': { type: 'string', description: 'Override build command' },
|
|
892
|
+
'lint-cmd': { type: 'string', description: 'Override lint command' },
|
|
893
|
+
'test-cmd': { type: 'string', description: 'Override test command' },
|
|
894
|
+
'coverage-cmd': { type: 'string', description: 'Override coverage command' },
|
|
895
|
+
profile: { type: 'string', description: 'Verification profile from .scale/verification.json' },
|
|
896
|
+
service: { type: 'string', description: 'Service name from .scale/verification.json' },
|
|
897
|
+
'artifact-gate': { type: 'string', description: 'Task artifact policy override: off, warn, or block' },
|
|
898
|
+
'require-artifacts': { type: 'boolean', default: false, description: 'Fail verification when required M/L/CRITICAL artifacts are incomplete' },
|
|
899
|
+
'require-installed-skills': { type: 'boolean', default: false, description: 'Fail verification when required workflow skills are not installed locally' },
|
|
900
|
+
'tool-gate': { type: 'string', description: 'Tool evidence policy override: off, advisory, evidence-required, or block' },
|
|
901
|
+
'require-tool-evidence': { type: 'boolean', default: false, description: 'Fail verification when required tool execution evidence is missing or skipped' },
|
|
902
|
+
'allow-skipped-tool-evidence': { type: 'boolean', default: false, description: 'Allow skipped/manual fallback tool evidence to satisfy the tool gate' },
|
|
903
|
+
'tdd-evidence': { type: 'string', description: 'Path to JSON TDD evidence with red/green/refactor/testFirst=true' },
|
|
904
|
+
'tdd-strict': { type: 'boolean', default: false, description: 'Require TDD evidence before other gates' },
|
|
905
|
+
'residual-risk': { type: 'string', description: 'Residual risk statement to record in task metrics' },
|
|
906
|
+
'skip-build': { type: 'boolean', default: false },
|
|
907
|
+
'skip-lint': { type: 'boolean', default: false },
|
|
908
|
+
'skip-test': { type: 'boolean', default: false },
|
|
909
|
+
json: { type: 'boolean', default: false },
|
|
910
|
+
},
|
|
911
|
+
async run({ args }) {
|
|
912
|
+
const { store, fsm, workflowEngine } = getEngine();
|
|
913
|
+
// Validate task exists
|
|
914
|
+
const task = await store.get(args['task-id']);
|
|
915
|
+
if (!task || task.type !== 'Task') {
|
|
916
|
+
console.error(`\nTask not found: ${args['task-id']}\n`);
|
|
917
|
+
process.exit(1);
|
|
918
|
+
}
|
|
919
|
+
const currentPayload = task.payload;
|
|
920
|
+
const taskServices = currentPayload.servicesTouched ?? [];
|
|
921
|
+
const taskFiles = currentPayload.filesInvolved?.length
|
|
922
|
+
? currentPayload.filesInvolved.map(normalizeGitPath)
|
|
923
|
+
: await detectTaskChangedFiles();
|
|
924
|
+
// === WorkflowEngine Integration ===
|
|
925
|
+
// Step 1: Run GateSystem G3-G7
|
|
926
|
+
if (!args.json)
|
|
927
|
+
console.log('\nRunning Quality Gates...');
|
|
928
|
+
const resolvedVerification = resolveVerificationTargets({
|
|
929
|
+
projectDir: PROJECT_DIR,
|
|
930
|
+
scaleDir: SCALE_DIR,
|
|
931
|
+
profile: args.profile,
|
|
932
|
+
service: args.service,
|
|
933
|
+
services: args.service ? undefined : taskServices,
|
|
934
|
+
});
|
|
935
|
+
if (!args.json) {
|
|
936
|
+
for (const warning of resolvedVerification.warnings)
|
|
937
|
+
console.log(` [WARN] ${warning}`);
|
|
938
|
+
for (const target of resolvedVerification.targets) {
|
|
939
|
+
if (target.service) {
|
|
940
|
+
console.log(` Service: ${target.service.name} (${target.service.path})`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
console.log(` Profile: ${resolvedVerification.profileName}`);
|
|
944
|
+
}
|
|
945
|
+
const gateResults = [];
|
|
946
|
+
for (const target of resolvedVerification.targets) {
|
|
947
|
+
if (!args.json && resolvedVerification.targets.length > 1) {
|
|
948
|
+
console.log(`\n Target: ${target.service?.name ?? 'root'}`);
|
|
949
|
+
}
|
|
950
|
+
const targetResults = await workflowEngine.verify({
|
|
951
|
+
cwd: target.config.cwd,
|
|
952
|
+
build: args['build-cmd'] ?? target.config.build,
|
|
953
|
+
lint: args['lint-cmd'] ?? target.config.lint,
|
|
954
|
+
test: args['test-cmd'] ?? target.config.test,
|
|
955
|
+
coverage: args['coverage-cmd'] ?? target.config.coverage,
|
|
956
|
+
smoke: target.config.smoke,
|
|
957
|
+
runtimeEvidence: {
|
|
958
|
+
projectDir: PROJECT_DIR,
|
|
959
|
+
scaleDir: SCALE_DIR,
|
|
960
|
+
taskId: args['task-id'],
|
|
961
|
+
profile: resolvedVerification.profileName,
|
|
962
|
+
},
|
|
963
|
+
tddEvidence: args['tdd-evidence'],
|
|
964
|
+
tddStrict: isTruthyFlag(args['tdd-strict']),
|
|
965
|
+
});
|
|
966
|
+
gateResults.push(...targetResults);
|
|
967
|
+
}
|
|
968
|
+
// Step 2: Display gate results
|
|
969
|
+
if (!args.json) {
|
|
970
|
+
console.log('\nGate Results:');
|
|
971
|
+
for (const result of gateResults) {
|
|
972
|
+
console.log(` ${result.passed ? '[PASS]' : '[FAIL]'} ${result.gate}: ${result.evidence.slice(0, 50)}`);
|
|
973
|
+
if (result.blockers.length > 0) {
|
|
974
|
+
result.blockers.forEach((b) => console.log(` [BLOCKER] ${b.slice(0, 80)}`));
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
// Extract results from gateResults
|
|
979
|
+
const g0Results = gateResults.filter(g => g.gate === 'G0');
|
|
980
|
+
const g4Results = gateResults.filter(g => g.gate === 'G4');
|
|
981
|
+
const g5Results = gateResults.filter(g => g.gate === 'G5');
|
|
982
|
+
const g6Results = gateResults.filter(g => g.gate === 'G6');
|
|
983
|
+
const g7Results = gateResults.filter(g => g.gate === 'G7');
|
|
984
|
+
const gatePassed = (results) => results.length > 0 && results.every(result => result.passed);
|
|
985
|
+
const buildExitCodes = g0Results
|
|
986
|
+
.flatMap(result => result.evidenceItems ?? [])
|
|
987
|
+
.filter(item => item.kind === 'command')
|
|
988
|
+
.map(item => item.exitCode)
|
|
989
|
+
.filter((code) => typeof code === 'number');
|
|
990
|
+
const results = {
|
|
991
|
+
buildStatus: gatePassed(g0Results) ? 'success' : 'failed',
|
|
992
|
+
buildExitCode: buildExitCodes.find(code => code !== 0) ?? (buildExitCodes.length > 0 ? 0 : undefined),
|
|
993
|
+
lintStatus: gatePassed(g4Results) ? 'success' : 'failed',
|
|
994
|
+
testPassed: gatePassed(g5Results),
|
|
995
|
+
testCoverage: undefined,
|
|
996
|
+
securityPassed: gatePassed(g7Results),
|
|
997
|
+
};
|
|
998
|
+
const verificationEvidenceIds = gateResults
|
|
999
|
+
.map(g => g.evidenceRecordId)
|
|
1000
|
+
.filter((id) => Boolean(id));
|
|
1001
|
+
// Extract coverage from G6 evidence
|
|
1002
|
+
const coverageValues = g6Results
|
|
1003
|
+
.map(result => result.evidence.match(/Coverage: (\d+\.?\d*)%/))
|
|
1004
|
+
.filter((match) => Boolean(match))
|
|
1005
|
+
.map(match => parseFloat(match[1]));
|
|
1006
|
+
if (coverageValues.length > 0)
|
|
1007
|
+
results.testCoverage = Math.min(...coverageValues);
|
|
1008
|
+
// Update Task payload with verification results
|
|
1009
|
+
const taskLevel = normalizeWorkflowLevel(currentPayload.workflowLevel ?? 'M');
|
|
1010
|
+
const verificationSkillPlan = taskLevel === 'S'
|
|
1011
|
+
? undefined
|
|
1012
|
+
: planSkillsForTask({
|
|
1013
|
+
taskId: args['task-id'],
|
|
1014
|
+
taskName: task.title,
|
|
1015
|
+
description: currentPayload.description,
|
|
1016
|
+
level: taskLevel,
|
|
1017
|
+
services: currentPayload.servicesTouched,
|
|
1018
|
+
files: taskFiles,
|
|
1019
|
+
});
|
|
1020
|
+
const verifiedServices = resolvedVerification.targets
|
|
1021
|
+
.map(target => target.service?.name)
|
|
1022
|
+
.filter((service) => Boolean(service));
|
|
1023
|
+
const updatedPayload = {
|
|
1024
|
+
...currentPayload,
|
|
1025
|
+
buildStatus: results.buildStatus,
|
|
1026
|
+
buildExitCode: results.buildExitCode,
|
|
1027
|
+
lintStatus: results.lintStatus,
|
|
1028
|
+
testPassed: results.testPassed,
|
|
1029
|
+
testCoverage: results.testCoverage,
|
|
1030
|
+
servicesTouched: currentPayload.servicesTouched?.length
|
|
1031
|
+
? currentPayload.servicesTouched
|
|
1032
|
+
: verifiedServices.length > 0 ? verifiedServices : currentPayload.servicesTouched,
|
|
1033
|
+
filesInvolved: currentPayload.filesInvolved?.length ? currentPayload.filesInvolved : taskFiles,
|
|
1034
|
+
residualRisk: args['residual-risk'] ?? currentPayload.residualRisk,
|
|
1035
|
+
verificationEvidenceIds,
|
|
1036
|
+
skillIntents: verificationSkillPlan?.intents.map(intent => intent.domain) ?? currentPayload.skillIntents,
|
|
1037
|
+
skillRoutingMode: verificationSkillPlan?.mode ?? currentPayload.skillRoutingMode,
|
|
1038
|
+
skillPlanRequired: verificationSkillPlan?.required ?? currentPayload.skillPlanRequired,
|
|
1039
|
+
requiredSkills: verificationSkillPlan?.requiredSkills ?? currentPayload.requiredSkills,
|
|
1040
|
+
recommendedSkills: verificationSkillPlan?.recommendedSkills ?? currentPayload.recommendedSkills,
|
|
1041
|
+
requiredSkillArtifacts: verificationSkillPlan?.requiredArtifacts ?? currentPayload.requiredSkillArtifacts,
|
|
1042
|
+
requiredSkillVerification: verificationSkillPlan?.requiredVerification ?? currentPayload.requiredSkillVerification,
|
|
1043
|
+
verifiedAt: Date.now(),
|
|
1044
|
+
};
|
|
1045
|
+
await store.update(args['task-id'], { payload: updatedPayload });
|
|
1046
|
+
const workflowWriter = new WorkflowArtifactWriter(SCALE_DIR);
|
|
1047
|
+
let workflowState = workflowWriter.updateCurrentState({
|
|
1048
|
+
taskId: args['task-id'],
|
|
1049
|
+
phase: 'verify',
|
|
1050
|
+
lastTaskId: args['task-id'],
|
|
1051
|
+
filesModified: updatedPayload.filesInvolved,
|
|
1052
|
+
skillIntents: updatedPayload.skillIntents,
|
|
1053
|
+
skillRoutingMode: updatedPayload.skillRoutingMode,
|
|
1054
|
+
skillPlanRequired: updatedPayload.skillPlanRequired,
|
|
1055
|
+
requiredSkills: updatedPayload.requiredSkills,
|
|
1056
|
+
recommendedSkills: updatedPayload.recommendedSkills,
|
|
1057
|
+
requiredSkillArtifacts: updatedPayload.requiredSkillArtifacts,
|
|
1058
|
+
requiredSkillVerification: updatedPayload.requiredSkillVerification,
|
|
1059
|
+
});
|
|
1060
|
+
const engineeringStandards = evaluateEngineeringStandardsGate({
|
|
1061
|
+
policy: resolvedVerification.policy,
|
|
1062
|
+
taskId: args['task-id'],
|
|
1063
|
+
artifactsDir: workflowState.artifactsDir,
|
|
1064
|
+
settle: Boolean(workflowState.artifactsDir),
|
|
1065
|
+
changedFiles: taskFiles.length > 0 ? taskFiles : undefined,
|
|
1066
|
+
});
|
|
1067
|
+
const metricLevel = metricLevelFromPayload(updatedPayload);
|
|
1068
|
+
const preArtifactCheck = metricLevel ? checkCurrentTaskArtifacts(metricLevel) : undefined;
|
|
1069
|
+
const artifactGate = evaluateArtifactGate({
|
|
1070
|
+
policy: resolvedVerification.policy,
|
|
1071
|
+
level: metricLevel,
|
|
1072
|
+
check: preArtifactCheck ? assumeVerificationArtifactWillBeWritten(preArtifactCheck) : undefined,
|
|
1073
|
+
cliMode: args['artifact-gate'],
|
|
1074
|
+
requireArtifacts: args['require-artifacts'],
|
|
1075
|
+
});
|
|
1076
|
+
const skillPolicy = loadSkillRoutingPolicy(PROJECT_DIR, SCALE_DIR);
|
|
1077
|
+
const skillGate = metricLevel && verificationSkillPlan
|
|
1078
|
+
? evaluateSkillGate({
|
|
1079
|
+
projectDir: PROJECT_DIR,
|
|
1080
|
+
artifactsDir: workflowState.artifactsDir,
|
|
1081
|
+
level: metricLevel,
|
|
1082
|
+
plan: verificationSkillPlan,
|
|
1083
|
+
enforceLevels: skillPolicy.policy.enforceLevels,
|
|
1084
|
+
})
|
|
1085
|
+
: undefined;
|
|
1086
|
+
const requireInstalledSkills = isTruthyFlag(args['require-installed-skills']);
|
|
1087
|
+
const skillInstallation = inspectRequiredWorkflowSkills(updatedPayload.requiredSkills ?? [], { projectDir: PROJECT_DIR });
|
|
1088
|
+
const skillInstallationBlocked = requireInstalledSkills && !skillInstallation.ok;
|
|
1089
|
+
const toolEvidenceGate = evaluateTaskToolEvidenceGate({
|
|
1090
|
+
skillPlan: verificationSkillPlan,
|
|
1091
|
+
level: metricLevel,
|
|
1092
|
+
cliMode: args['tool-gate'],
|
|
1093
|
+
requireEvidence: args['require-tool-evidence'],
|
|
1094
|
+
allowSkipped: args['allow-skipped-tool-evidence'],
|
|
1095
|
+
});
|
|
1096
|
+
const workflowOpenTaskBlockers = blockingWorkflowOpenTasks(workflowState.openTasks, args['task-id']);
|
|
1097
|
+
const workflowOpenTasksBlocked = workflowOpenTaskBlockers.length > 0;
|
|
1098
|
+
// Attempt FSM transition to COMPLETED
|
|
1099
|
+
// Guards: build_passed, lint_passed, tests_passed, open workflow tasks, and optional artifact policy.
|
|
1100
|
+
const codePassed = results.buildStatus === 'success' &&
|
|
1101
|
+
(results.buildExitCode ?? 1) === 0 &&
|
|
1102
|
+
results.lintStatus === 'success' &&
|
|
1103
|
+
results.testPassed === true &&
|
|
1104
|
+
(results.testCoverage ?? 0) >= 80 &&
|
|
1105
|
+
results.securityPassed === true;
|
|
1106
|
+
const completionEligible = codePassed &&
|
|
1107
|
+
!artifactGate.blocked &&
|
|
1108
|
+
!(skillGate?.blocked ?? false) &&
|
|
1109
|
+
!skillInstallationBlocked &&
|
|
1110
|
+
!engineeringStandards.blocked &&
|
|
1111
|
+
!(toolEvidenceGate?.blocked ?? false) &&
|
|
1112
|
+
!workflowOpenTasksBlocked;
|
|
1113
|
+
let transitionResult = null;
|
|
1114
|
+
if (completionEligible) {
|
|
1115
|
+
const completeResult = await fsm.canTransition(args['task-id'], 'complete');
|
|
1116
|
+
if (!completeResult.allowed) {
|
|
1117
|
+
if (!args.json) {
|
|
1118
|
+
console.error('\nFSM transition blocked: RUNNING -> COMPLETED');
|
|
1119
|
+
console.error(' Task cannot be completed due to:');
|
|
1120
|
+
completeResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
1121
|
+
}
|
|
1122
|
+
// Don't exit - allow user to see what passed and fix issues
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
transitionResult = await fsm.transition(args['task-id'], 'complete', {
|
|
1126
|
+
actor: { kind: 'human', userId: 'cli' }
|
|
1127
|
+
});
|
|
1128
|
+
if (!args.json)
|
|
1129
|
+
console.log('\n FSM: RUNNING -> COMPLETED');
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
else if (!args.json && !codePassed) {
|
|
1133
|
+
console.log('\n Verification requirements not met - cannot complete Task');
|
|
1134
|
+
}
|
|
1135
|
+
else if (!args.json && artifactGate.blocked) {
|
|
1136
|
+
console.log('\n Artifact gate blocked completion - required task artifacts are incomplete');
|
|
1137
|
+
}
|
|
1138
|
+
else if (!args.json && skillGate?.blocked) {
|
|
1139
|
+
console.log('\n Skill gate blocked completion - required skill evidence artifacts are incomplete');
|
|
1140
|
+
}
|
|
1141
|
+
else if (!args.json && skillInstallationBlocked) {
|
|
1142
|
+
console.log('\n Skill installation gate blocked completion - required workflow skills are missing');
|
|
1143
|
+
}
|
|
1144
|
+
else if (!args.json && engineeringStandards.blocked) {
|
|
1145
|
+
console.log('\n Engineering standards gate blocked completion - fix blocking standards findings');
|
|
1146
|
+
}
|
|
1147
|
+
else if (!args.json && toolEvidenceGate?.blocked) {
|
|
1148
|
+
console.log('\n Tool evidence gate blocked completion - required tools need passed execution evidence');
|
|
1149
|
+
}
|
|
1150
|
+
else if (!args.json && workflowOpenTasksBlocked) {
|
|
1151
|
+
console.log('\n Workflow open tasks blocked completion - finish required workflow commands first');
|
|
1152
|
+
}
|
|
1153
|
+
const passed = completionEligible && (transitionResult?.success ?? false);
|
|
1154
|
+
if (passed) {
|
|
1155
|
+
workflowState = workflowWriter.updateCurrentState({
|
|
1156
|
+
openTasks: removeWorkflowOpenTask(workflowState.openTasks, 'verification'),
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
const verificationArtifactPath = appendVerificationArtifact({
|
|
1160
|
+
projectDir: PROJECT_DIR,
|
|
1161
|
+
artifactsDir: workflowState.artifactsDir,
|
|
1162
|
+
taskId: args['task-id'],
|
|
1163
|
+
profile: resolvedVerification.profileName,
|
|
1164
|
+
services: verifiedServices,
|
|
1165
|
+
gateResults,
|
|
1166
|
+
passed,
|
|
1167
|
+
});
|
|
1168
|
+
const artifactCheck = metricLevel ? checkCurrentTaskArtifacts(metricLevel) : undefined;
|
|
1169
|
+
const finalArtifactGate = artifactCheck
|
|
1170
|
+
? evaluateArtifactGate({
|
|
1171
|
+
policy: resolvedVerification.policy,
|
|
1172
|
+
level: metricLevel,
|
|
1173
|
+
check: artifactCheck,
|
|
1174
|
+
cliMode: args['artifact-gate'],
|
|
1175
|
+
requireArtifacts: args['require-artifacts'],
|
|
1176
|
+
})
|
|
1177
|
+
: artifactGate;
|
|
1178
|
+
const finalSkillGate = metricLevel && verificationSkillPlan
|
|
1179
|
+
? evaluateSkillGate({
|
|
1180
|
+
projectDir: PROJECT_DIR,
|
|
1181
|
+
artifactsDir: workflowState.artifactsDir,
|
|
1182
|
+
level: metricLevel,
|
|
1183
|
+
plan: verificationSkillPlan,
|
|
1184
|
+
enforceLevels: skillPolicy.policy.enforceLevels,
|
|
1185
|
+
})
|
|
1186
|
+
: skillGate;
|
|
1187
|
+
const finalToolEvidenceGate = evaluateTaskToolEvidenceGate({
|
|
1188
|
+
skillPlan: verificationSkillPlan,
|
|
1189
|
+
level: metricLevel,
|
|
1190
|
+
cliMode: args['tool-gate'],
|
|
1191
|
+
requireEvidence: args['require-tool-evidence'],
|
|
1192
|
+
allowSkipped: args['allow-skipped-tool-evidence'],
|
|
1193
|
+
}) ?? toolEvidenceGate;
|
|
1194
|
+
const finalPayload = {
|
|
1195
|
+
...updatedPayload,
|
|
1196
|
+
artifactGateMode: finalArtifactGate.mode,
|
|
1197
|
+
artifactGatePassed: !finalArtifactGate.blocked,
|
|
1198
|
+
artifactComplete: artifactCheck?.complete,
|
|
1199
|
+
skillGatePassed: finalSkillGate ? !finalSkillGate.blocked && !skillInstallationBlocked : !skillInstallationBlocked,
|
|
1200
|
+
toolOrchestrationMode: finalToolEvidenceGate?.mode,
|
|
1201
|
+
requiredTools: finalToolEvidenceGate?.requiredTools,
|
|
1202
|
+
toolEvidenceIds: finalToolEvidenceGate?.passed.map(item => item.evidenceId).filter((id) => Boolean(id)),
|
|
1203
|
+
toolEvidenceGatePassed: finalToolEvidenceGate ? !finalToolEvidenceGate.blocked : true,
|
|
1204
|
+
};
|
|
1205
|
+
await store.update(args['task-id'], { payload: finalPayload });
|
|
1206
|
+
const metricGateStatus = (finalArtifactGate.blocked || finalSkillGate?.blocked || skillInstallationBlocked || engineeringStandards.blocked || finalToolEvidenceGate?.blocked || workflowOpenTasksBlocked)
|
|
1207
|
+
? 'blocked'
|
|
1208
|
+
: undefined;
|
|
1209
|
+
const metricRecord = await recordVerificationMetric({
|
|
1210
|
+
taskId: args['task-id'],
|
|
1211
|
+
taskName: task.title,
|
|
1212
|
+
taskPayload: finalPayload,
|
|
1213
|
+
passed,
|
|
1214
|
+
serviceNames: verifiedServices,
|
|
1215
|
+
artifactCheck,
|
|
1216
|
+
finalGateStatus: metricGateStatus,
|
|
1217
|
+
});
|
|
1218
|
+
const result = {
|
|
1219
|
+
phase: 'VERIFY',
|
|
1220
|
+
taskId: args['task-id'],
|
|
1221
|
+
profile: resolvedVerification.profileName,
|
|
1222
|
+
service: verifiedServices.length === 1 ? verifiedServices[0] : undefined,
|
|
1223
|
+
services: verifiedServices,
|
|
1224
|
+
results,
|
|
1225
|
+
evidenceIds: verificationEvidenceIds,
|
|
1226
|
+
verificationArtifactPath,
|
|
1227
|
+
artifactCheck,
|
|
1228
|
+
artifactGate: finalArtifactGate,
|
|
1229
|
+
engineeringStandards,
|
|
1230
|
+
skillGate: finalSkillGate,
|
|
1231
|
+
toolEvidenceGate: finalToolEvidenceGate,
|
|
1232
|
+
workflowOpenTasks: {
|
|
1233
|
+
blocked: workflowOpenTasksBlocked,
|
|
1234
|
+
blockers: workflowOpenTaskBlockers,
|
|
1235
|
+
openTasks: workflowState.openTasks ?? [],
|
|
1236
|
+
},
|
|
1237
|
+
skillInstallation: {
|
|
1238
|
+
...skillInstallation,
|
|
1239
|
+
checked: requireInstalledSkills,
|
|
1240
|
+
blocked: skillInstallationBlocked,
|
|
1241
|
+
},
|
|
1242
|
+
metric: metricRecord,
|
|
1243
|
+
passed
|
|
1244
|
+
};
|
|
1245
|
+
if (args.json)
|
|
1246
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1247
|
+
else {
|
|
1248
|
+
console.log(`\nVERIFY: ${passed ? 'PASSED' : 'FAILED'}`);
|
|
1249
|
+
if (metricRecord)
|
|
1250
|
+
console.log(` Metrics: ${metricRecord.taskId} ${metricRecord.finalGateStatus} (fix iterations: ${metricRecord.fixIterations})`);
|
|
1251
|
+
if (artifactCheck && !artifactCheck.complete) {
|
|
1252
|
+
console.log(` Artifact gaps: ${artifactCheck.missing.length} missing, ${artifactCheck.incomplete.length} incomplete`);
|
|
1253
|
+
}
|
|
1254
|
+
if (finalSkillGate && !finalSkillGate.complete) {
|
|
1255
|
+
console.log(` Skill evidence gaps: ${finalSkillGate.missing.length} missing, ${finalSkillGate.incomplete.length} incomplete`);
|
|
1256
|
+
}
|
|
1257
|
+
if (skillInstallationBlocked) {
|
|
1258
|
+
console.log(` Missing required workflow skills: ${skillInstallation.missing.join(', ')}`);
|
|
1259
|
+
}
|
|
1260
|
+
if (engineeringStandards.blocked) {
|
|
1261
|
+
console.log(` Engineering standards blockers: ${engineeringStandards.findings.filter(finding => finding.severity === 'fail').length}`);
|
|
1262
|
+
}
|
|
1263
|
+
if (finalToolEvidenceGate?.blocked) {
|
|
1264
|
+
console.log(` Tool evidence gaps: ${finalToolEvidenceGate.missing.length} missing, ${finalToolEvidenceGate.failed.length} failed, ${finalToolEvidenceGate.skipped.length} skipped`);
|
|
1265
|
+
}
|
|
1266
|
+
if (passed)
|
|
1267
|
+
console.log(`\n Next: scale review\n`);
|
|
1268
|
+
else
|
|
1269
|
+
console.log(`\n Fix issues and re-run: scale verify ${args['task-id']}\n`);
|
|
1270
|
+
}
|
|
1271
|
+
},
|
|
1272
|
+
});
|
|
1273
|
+
async function runGit(args) {
|
|
1274
|
+
const { execa } = await import('execa');
|
|
1275
|
+
const result = await execa('git', args, { cwd: PROJECT_DIR, reject: false });
|
|
1276
|
+
return {
|
|
1277
|
+
exitCode: result.exitCode ?? 1,
|
|
1278
|
+
stdout: result.stdout ?? '',
|
|
1279
|
+
stderr: result.stderr ?? '',
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
function mergeUntrackedFilesIntoStatus(statusOutput, untrackedOutput) {
|
|
1283
|
+
const existing = new Set(parseChangedFiles(statusOutput).map(file => file.path.replace(/\\/g, '/')));
|
|
1284
|
+
// Add '??' status marker for untracked files so parseChangedFiles can recognize them
|
|
1285
|
+
const additions = untrackedOutput
|
|
1286
|
+
.split('\n')
|
|
1287
|
+
.map(line => line.trim())
|
|
1288
|
+
.filter(Boolean)
|
|
1289
|
+
.filter(path => shouldReviewFile(path))
|
|
1290
|
+
.filter(path => !existing.has(path.replace(/\\/g, '/')))
|
|
1291
|
+
.map(path => `?? ${path}`); // Add status marker
|
|
1292
|
+
return [statusOutput.trim(), ...additions].filter(Boolean).join('\n');
|
|
1293
|
+
}
|
|
1294
|
+
function readUntrackedFileAsDiff(path) {
|
|
1295
|
+
try {
|
|
1296
|
+
const stat = statSync(path);
|
|
1297
|
+
if (!stat.isFile() || stat.size > 250_000)
|
|
1298
|
+
return '';
|
|
1299
|
+
const content = readFileSync(path, 'utf-8');
|
|
1300
|
+
if (content.includes('\u0000'))
|
|
1301
|
+
return '';
|
|
1302
|
+
return content
|
|
1303
|
+
.split('\n')
|
|
1304
|
+
.slice(0, 2000)
|
|
1305
|
+
.map(line => `+${line}`)
|
|
1306
|
+
.join('\n');
|
|
1307
|
+
}
|
|
1308
|
+
catch {
|
|
1309
|
+
return '';
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
async function reviewGitChanges(taskPayload) {
|
|
1313
|
+
const status = await runGit(['status', '--short']);
|
|
1314
|
+
const untracked = await runGit(['ls-files', '--others', '--exclude-standard']);
|
|
1315
|
+
let statusOutput = mergeUntrackedFilesIntoStatus(status.stdout, untracked.stdout);
|
|
1316
|
+
// Scope review to task-relevant files only.
|
|
1317
|
+
// When filesInvolved is set, only analyze those files.
|
|
1318
|
+
// When empty, only analyze untracked (new) files to avoid picking up
|
|
1319
|
+
// unrelated modifications from a dirty working tree.
|
|
1320
|
+
if (taskPayload?.filesInvolved?.length) {
|
|
1321
|
+
const involved = new Set(taskPayload.filesInvolved.map(f => f.replace(/\\/g, '/')));
|
|
1322
|
+
statusOutput = statusOutput.split('\n').filter(line => {
|
|
1323
|
+
const parsed = parseChangedFiles(line);
|
|
1324
|
+
return parsed.length > 0 && involved.has(parsed[0].path.replace(/\\/g, '/'));
|
|
1325
|
+
}).join('\n');
|
|
1326
|
+
}
|
|
1327
|
+
else {
|
|
1328
|
+
// Only include untracked files (status '??') — skip tracked modifications
|
|
1329
|
+
// that may be unrelated to the task under review.
|
|
1330
|
+
statusOutput = statusOutput.split('\n').filter(line => line.startsWith('??')).join('\n');
|
|
1331
|
+
}
|
|
1332
|
+
const verificationEvidence = getVerificationEvidenceSummary(taskPayload?.verificationEvidenceIds);
|
|
1333
|
+
const changedFiles = analyzeReview({ statusOutput, diffs: [], taskPayload, verificationEvidence }).changedFiles;
|
|
1334
|
+
const diffs = [];
|
|
1335
|
+
for (const file of changedFiles.slice(0, 50)) {
|
|
1336
|
+
if (file.status === '??') {
|
|
1337
|
+
diffs.push({ file: file.path, text: readUntrackedFileAsDiff(file.path) });
|
|
1338
|
+
}
|
|
1339
|
+
else {
|
|
1340
|
+
const diff = await runGit(['diff', '--', file.path]);
|
|
1341
|
+
diffs.push({ file: file.path, text: diff.stdout });
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
return analyzeReview({ statusOutput, diffs, taskPayload, verificationEvidence });
|
|
1345
|
+
}
|
|
1346
|
+
function collectReviewedFiles(records) {
|
|
1347
|
+
const reviewed = new Set();
|
|
1348
|
+
for (const record of records) {
|
|
1349
|
+
if (!record.passed)
|
|
1350
|
+
continue;
|
|
1351
|
+
for (const file of record.changedFiles) {
|
|
1352
|
+
if (shouldReviewFile(file))
|
|
1353
|
+
reviewed.add(normalizeGitPath(file));
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
return reviewed;
|
|
1357
|
+
}
|
|
1358
|
+
async function getReviewableGitChanges() {
|
|
1359
|
+
const status = await runGit(['status', '--short']);
|
|
1360
|
+
const untracked = await runGit(['ls-files', '--others', '--exclude-standard']);
|
|
1361
|
+
const statusOutput = mergeUntrackedFilesIntoStatus(status.stdout, untracked.stdout);
|
|
1362
|
+
return parseChangedFiles(statusOutput).filter(file => shouldReviewFile(file.path));
|
|
1363
|
+
}
|
|
1364
|
+
async function stageReviewedFiles(reviewRecords) {
|
|
1365
|
+
const reviewedFiles = collectReviewedFiles(reviewRecords);
|
|
1366
|
+
const currentChanges = await getReviewableGitChanges();
|
|
1367
|
+
const stagedFiles = [];
|
|
1368
|
+
const unreviewedFiles = [];
|
|
1369
|
+
// Edge case: if currentChanges is empty but reviewedFiles has files that should be staged,
|
|
1370
|
+
// this indicates files were deleted or moved. Treat reviewed but missing files as unreviewed.
|
|
1371
|
+
if (currentChanges.length === 0 && reviewedFiles.size > 0) {
|
|
1372
|
+
// No changes to stage, but we have review records - this is a pass (nothing to commit)
|
|
1373
|
+
return { stagedFiles: [], unreviewedFiles: [] };
|
|
1374
|
+
}
|
|
1375
|
+
for (const file of currentChanges) {
|
|
1376
|
+
const normalizedPath = normalizeGitPath(file.path);
|
|
1377
|
+
if (reviewedFiles.has(normalizedPath)) {
|
|
1378
|
+
stagedFiles.push(file.path);
|
|
1379
|
+
}
|
|
1380
|
+
else {
|
|
1381
|
+
unreviewedFiles.push(file.path);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
// Only block if there are actual unreviewed changes
|
|
1385
|
+
if (unreviewedFiles.length > 0) {
|
|
1386
|
+
return { stagedFiles: [], unreviewedFiles };
|
|
1387
|
+
}
|
|
1388
|
+
if (stagedFiles.length > 0) {
|
|
1389
|
+
const gitAdd = await runGit(['add', '--', ...stagedFiles]);
|
|
1390
|
+
if (gitAdd.exitCode !== 0) {
|
|
1391
|
+
throw new Error(gitAdd.stderr || 'git add failed');
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return { stagedFiles, unreviewedFiles: [] };
|
|
1395
|
+
}
|
|
1396
|
+
function isMultiRepositoryTopology(topology) {
|
|
1397
|
+
return topology === 'moe' || topology === 'submodule-workspace' || topology === 'polyrepo';
|
|
1398
|
+
}
|
|
1399
|
+
function hasChildRepositoryChange(path, childPath) {
|
|
1400
|
+
const normalized = normalizeGitPath(path);
|
|
1401
|
+
const child = normalizeGitPath(childPath).replace(/\/+$/, '');
|
|
1402
|
+
return normalized === child || normalized.startsWith(`${child}/`);
|
|
1403
|
+
}
|
|
1404
|
+
async function validateWorkspaceShipBoundary() {
|
|
1405
|
+
try {
|
|
1406
|
+
const report = await inspectWorkspaceLifecycle({ projectDir: PROJECT_DIR });
|
|
1407
|
+
const blockers = [];
|
|
1408
|
+
const warnings = [...report.topology.warnings];
|
|
1409
|
+
const policy = report.topology.finishPolicy;
|
|
1410
|
+
const rootChanges = await getReviewableGitChanges();
|
|
1411
|
+
blockers.push(...report.branchPolicy.shipBlockers);
|
|
1412
|
+
warnings.push(...report.branchPolicy.warnings);
|
|
1413
|
+
if (!report.topology.configured && report.childRepositories.length > 0) {
|
|
1414
|
+
const changedChildRepositories = report.childRepositories
|
|
1415
|
+
.filter(child => rootChanges.some(file => hasChildRepositoryChange(file.path, child.relativePath)))
|
|
1416
|
+
.map(child => child.relativePath);
|
|
1417
|
+
const dirtyChildRepositories = report.childRepositories
|
|
1418
|
+
.filter(child => !child.clean || child.ahead > 0)
|
|
1419
|
+
.map(child => child.relativePath);
|
|
1420
|
+
const affected = Array.from(new Set([...changedChildRepositories, ...dirtyChildRepositories]));
|
|
1421
|
+
if (affected.length > 0) {
|
|
1422
|
+
blockers.push(`Workspace topology is not configured; child repository state is present at ${affected.join(', ')}. Create .scale/workspace.json with scale workspace map --write --topology moe before shipping.`);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
if (report.topology.configured && isMultiRepositoryTopology(report.topology.topology)) {
|
|
1426
|
+
for (const child of report.childRepositories) {
|
|
1427
|
+
if (policy.requireCleanRepositories && !child.clean) {
|
|
1428
|
+
blockers.push(`Child repository ${child.relativePath} has uncommitted changes`);
|
|
1429
|
+
}
|
|
1430
|
+
if (policy.requirePushedBranches && child.upstream && child.ahead > 0) {
|
|
1431
|
+
blockers.push(`Child repository ${child.relativePath} has unpushed commits`);
|
|
1432
|
+
}
|
|
1433
|
+
if (policy.requirePushedBranches && report.topology.topology === 'moe' && !child.upstream && child.branch) {
|
|
1434
|
+
blockers.push(`Child repository ${child.relativePath} has no upstream; push or explicitly disable requirePushedBranches before shipping`);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
return { report, blockers, warnings };
|
|
1439
|
+
}
|
|
1440
|
+
catch (error) {
|
|
1441
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1442
|
+
return {
|
|
1443
|
+
report: null,
|
|
1444
|
+
blockers: [`Workspace boundary check could not inspect Git repositories: ${message}`],
|
|
1445
|
+
warnings: [],
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
function collectTaskReviewText(taskPayload) {
|
|
1450
|
+
if (!taskPayload)
|
|
1451
|
+
return '';
|
|
1452
|
+
const brief = taskPayload.agentBrief;
|
|
1453
|
+
const parts = [
|
|
1454
|
+
taskPayload.description,
|
|
1455
|
+
taskPayload.workflowLevel,
|
|
1456
|
+
taskPayload.residualRisk,
|
|
1457
|
+
...(taskPayload.servicesTouched ?? []),
|
|
1458
|
+
...(taskPayload.filesInvolved ?? []),
|
|
1459
|
+
...(taskPayload.requiredCapabilities ?? []),
|
|
1460
|
+
...(taskPayload.skillIntents ?? []),
|
|
1461
|
+
...(taskPayload.requiredSkills ?? []),
|
|
1462
|
+
...(taskPayload.recommendedSkills ?? []),
|
|
1463
|
+
brief?.category,
|
|
1464
|
+
brief?.summary,
|
|
1465
|
+
brief?.currentBehavior,
|
|
1466
|
+
brief?.desiredBehavior,
|
|
1467
|
+
...(brief?.keyInterfaces ?? []),
|
|
1468
|
+
...(brief?.acceptanceCriteria ?? []),
|
|
1469
|
+
...(brief?.outOfScope ?? []),
|
|
1470
|
+
];
|
|
1471
|
+
return parts
|
|
1472
|
+
.filter((value) => typeof value === 'string' && value.trim().length > 0)
|
|
1473
|
+
.join('\n')
|
|
1474
|
+
.toLowerCase();
|
|
1475
|
+
}
|
|
1476
|
+
function isDeclaredReviewFile(path, declaredFiles) {
|
|
1477
|
+
const normalized = normalizeGitPath(path);
|
|
1478
|
+
if (declaredFiles.has(normalized))
|
|
1479
|
+
return true;
|
|
1480
|
+
for (const declared of declaredFiles) {
|
|
1481
|
+
const clean = declared.replace(/\/+$/, '');
|
|
1482
|
+
if (clean && normalized.startsWith(`${clean}/`))
|
|
1483
|
+
return true;
|
|
1484
|
+
}
|
|
1485
|
+
return false;
|
|
1486
|
+
}
|
|
1487
|
+
function pathTraceableToTaskText(path, taskText) {
|
|
1488
|
+
if (!taskText)
|
|
1489
|
+
return false;
|
|
1490
|
+
const normalized = normalizeGitPath(path).toLowerCase();
|
|
1491
|
+
if (taskText.includes(normalized))
|
|
1492
|
+
return true;
|
|
1493
|
+
const ignored = new Set(['src', 'lib', 'test', 'tests', 'spec', 'index', 'main', 'types', 'utils', 'docs']);
|
|
1494
|
+
const tokens = normalized
|
|
1495
|
+
.split(/[\/_.-]+/)
|
|
1496
|
+
.map(token => token.trim())
|
|
1497
|
+
.filter(token => token.length >= 4 && !ignored.has(token));
|
|
1498
|
+
return tokens.some(token => taskText.includes(token));
|
|
1499
|
+
}
|
|
1500
|
+
function hasTaskHypotheses(taskPayload) {
|
|
1501
|
+
if (!taskPayload)
|
|
1502
|
+
return false;
|
|
1503
|
+
const brief = taskPayload.agentBrief;
|
|
1504
|
+
return Boolean((brief?.currentBehavior && brief.desiredBehavior && (brief.acceptanceCriteria?.length ?? 0) > 0) ||
|
|
1505
|
+
(taskPayload.skillIntents?.length ?? 0) > 0 ||
|
|
1506
|
+
(taskPayload.requiredSkills?.length ?? 0) > 0 ||
|
|
1507
|
+
(taskPayload.requiredCapabilities?.length ?? 0) > 0);
|
|
1508
|
+
}
|
|
1509
|
+
function hasVerifiableTaskGoal(taskPayload) {
|
|
1510
|
+
if (!taskPayload)
|
|
1511
|
+
return false;
|
|
1512
|
+
const brief = taskPayload.agentBrief;
|
|
1513
|
+
const text = collectTaskReviewText(taskPayload);
|
|
1514
|
+
return Boolean((taskPayload.verificationEvidenceIds?.length ?? 0) > 0 ||
|
|
1515
|
+
taskPayload.testPassed === true ||
|
|
1516
|
+
taskPayload.buildStatus === 'success' ||
|
|
1517
|
+
taskPayload.lintStatus === 'success' ||
|
|
1518
|
+
(brief?.acceptanceCriteria?.length ?? 0) > 0 ||
|
|
1519
|
+
/\b(verify|verified|test|coverage|acceptance|criteria|evidence|gate)\b/.test(text));
|
|
1520
|
+
}
|
|
1521
|
+
function hasOutOfScopeReviewChange(reviewedFiles, taskPayload) {
|
|
1522
|
+
const outOfScope = taskPayload?.agentBrief?.outOfScope ?? [];
|
|
1523
|
+
if (outOfScope.length === 0 || reviewedFiles.length === 0)
|
|
1524
|
+
return false;
|
|
1525
|
+
const changedText = reviewedFiles.join('\n').toLowerCase();
|
|
1526
|
+
return outOfScope
|
|
1527
|
+
.map(item => item.toLowerCase().trim())
|
|
1528
|
+
.filter(item => item.length >= 4)
|
|
1529
|
+
.some(item => changedText.includes(item));
|
|
1530
|
+
}
|
|
1531
|
+
function deriveReviewKarpathyContext(review, taskPayload) {
|
|
1532
|
+
const reviewedFiles = review.changedFiles
|
|
1533
|
+
.map(file => normalizeGitPath(file.path))
|
|
1534
|
+
.filter(path => shouldReviewFile(path));
|
|
1535
|
+
const declaredFiles = new Set((taskPayload?.filesInvolved ?? []).map(normalizeGitPath));
|
|
1536
|
+
const taskText = collectTaskReviewText(taskPayload);
|
|
1537
|
+
const changesTraceable = reviewedFiles.length === 0 || reviewedFiles.every(file => isDeclaredReviewFile(file, declaredFiles) || pathTraceableToTaskText(file, taskText));
|
|
1538
|
+
const hasExtraFeatures = hasOutOfScopeReviewChange(reviewedFiles, taskPayload) ||
|
|
1539
|
+
review.findings.some(finding => /extra|out[-\s]?of[-\s]?scope|scope creep/i.test(`${finding.category} ${finding.description}`));
|
|
1540
|
+
return {
|
|
1541
|
+
hypothesesListed: hasTaskHypotheses(taskPayload) || reviewedFiles.length === 0,
|
|
1542
|
+
hasExtraFeatures,
|
|
1543
|
+
changesTraceable,
|
|
1544
|
+
hasVerifiableGoal: hasVerifiableTaskGoal(taskPayload) || reviewedFiles.length === 0,
|
|
1545
|
+
};
|
|
1546
|
+
}
|
|
1547
|
+
// REVIEW Phase - KarpathyEvaluator + deterministic review evidence
|
|
1548
|
+
export const phaseReview = defineCommand({
|
|
1549
|
+
meta: { name: 'review', description: 'REVIEW: Code review with Karpathy Principles (/review)' },
|
|
1550
|
+
args: {
|
|
1551
|
+
'task-id': { type: 'positional', required: false },
|
|
1552
|
+
'check-security': { type: 'boolean', default: true },
|
|
1553
|
+
'check-style': { type: 'boolean', default: true },
|
|
1554
|
+
format: { type: 'string', alias: 'f', description: 'Output format: html or md (default: html)' },
|
|
1555
|
+
brand: { type: 'string', description: 'Brand theme for HTML output (vercel/stripe/notion/linear/github)' },
|
|
1556
|
+
json: { type: 'boolean', default: false },
|
|
1557
|
+
},
|
|
1558
|
+
async run({ args }) {
|
|
1559
|
+
const { store, workflowEngine } = getEngine();
|
|
1560
|
+
const reviewStore = new ReviewStore(SCALE_DIR);
|
|
1561
|
+
// If task-id provided, validate task exists
|
|
1562
|
+
let task = null;
|
|
1563
|
+
let taskPayload;
|
|
1564
|
+
if (args['task-id']) {
|
|
1565
|
+
task = await store.get(args['task-id']);
|
|
1566
|
+
if (!task || task.type !== 'Task') {
|
|
1567
|
+
console.error(`\nTask not found: ${args['task-id']}\n`);
|
|
1568
|
+
process.exit(1);
|
|
1569
|
+
}
|
|
1570
|
+
taskPayload = task.payload;
|
|
1571
|
+
}
|
|
1572
|
+
const review = await reviewGitChanges(taskPayload);
|
|
1573
|
+
const karpathyContext = deriveReviewKarpathyContext(review, taskPayload);
|
|
1574
|
+
const karpathyResult = workflowEngine.checkKarpathy(karpathyContext);
|
|
1575
|
+
const karpathyReport = {
|
|
1576
|
+
context: karpathyContext,
|
|
1577
|
+
checks: karpathyResult,
|
|
1578
|
+
passed: karpathyResult.every(check => check.passed),
|
|
1579
|
+
violations: workflowEngine.getKarpathyEvaluator().getViolations(),
|
|
1580
|
+
};
|
|
1581
|
+
if (!args.json) {
|
|
1582
|
+
console.log('\nKarpathy Principles Check:');
|
|
1583
|
+
console.log(` Derived context: hypotheses=${karpathyContext.hypothesesListed}, extraFeatures=${karpathyContext.hasExtraFeatures}, traceable=${karpathyContext.changesTraceable}, verifiableGoal=${karpathyContext.hasVerifiableGoal}`);
|
|
1584
|
+
console.log(workflowEngine.getKarpathyEvaluator().formatReport());
|
|
1585
|
+
}
|
|
1586
|
+
const findings = review.findings;
|
|
1587
|
+
const summary = summarizeFindings(findings);
|
|
1588
|
+
const passed = summary.critical === 0 && summary.high === 0;
|
|
1589
|
+
const record = reviewStore.saveReview({
|
|
1590
|
+
taskId: args['task-id'],
|
|
1591
|
+
passed,
|
|
1592
|
+
findings,
|
|
1593
|
+
changedFiles: review.changedFiles.map(file => normalizeGitPath(file.path)),
|
|
1594
|
+
summary,
|
|
1595
|
+
});
|
|
1596
|
+
if (task && taskPayload) {
|
|
1597
|
+
const updatedPayload = {
|
|
1598
|
+
...taskPayload,
|
|
1599
|
+
reviewPassed: passed,
|
|
1600
|
+
reviewEvidenceIds: [...(taskPayload.reviewEvidenceIds ?? []), record.id],
|
|
1601
|
+
reviewedAt: Date.now(),
|
|
1602
|
+
};
|
|
1603
|
+
await store.update(task.id, { payload: updatedPayload });
|
|
1604
|
+
}
|
|
1605
|
+
// Generate review HTML file (default format: html)
|
|
1606
|
+
const reviewOutputFormat = args.format ?? 'md';
|
|
1607
|
+
let reviewHtmlPath;
|
|
1608
|
+
if (reviewOutputFormat === 'html') {
|
|
1609
|
+
const reviewRenderer = new HTMLDocumentRenderer({
|
|
1610
|
+
title: `Review ${record.id}`,
|
|
1611
|
+
brand: args.brand,
|
|
1612
|
+
version: SCALE_ENGINE_VERSION,
|
|
1613
|
+
status: passed ? 'PASS' : 'FAIL',
|
|
1614
|
+
});
|
|
1615
|
+
const reviewHtml = reviewRenderer.renderReview({
|
|
1616
|
+
id: record.id,
|
|
1617
|
+
title: `Code Review — ${record.id}`,
|
|
1618
|
+
timestamp: new Date().toISOString(),
|
|
1619
|
+
findings: findings.map(f => ({
|
|
1620
|
+
severity: f.severity,
|
|
1621
|
+
file: f.file ?? '',
|
|
1622
|
+
message: f.description,
|
|
1623
|
+
})),
|
|
1624
|
+
passed,
|
|
1625
|
+
specCoverage: undefined,
|
|
1626
|
+
specFindings: undefined,
|
|
1627
|
+
});
|
|
1628
|
+
const reviewsDir = join(SCALE_DIR, 'reviews');
|
|
1629
|
+
ensureDir(reviewsDir);
|
|
1630
|
+
reviewHtmlPath = join(reviewsDir, `${record.id}.html`);
|
|
1631
|
+
reviewRenderer.writeToFile(reviewHtml, reviewHtmlPath);
|
|
1632
|
+
}
|
|
1633
|
+
const result = {
|
|
1634
|
+
phase: 'REVIEW',
|
|
1635
|
+
taskId: args['task-id'],
|
|
1636
|
+
reviewId: record.id,
|
|
1637
|
+
reviewHtmlPath,
|
|
1638
|
+
findings,
|
|
1639
|
+
changedFiles: review.changedFiles.map(file => normalizeGitPath(file.path)),
|
|
1640
|
+
summary,
|
|
1641
|
+
karpathy: karpathyReport,
|
|
1642
|
+
passed,
|
|
1643
|
+
format: reviewOutputFormat,
|
|
1644
|
+
recommendation: passed
|
|
1645
|
+
? karpathyReport.passed ? 'Ready to ship' : 'Review passed; address Karpathy advisory warnings before release hardening'
|
|
1646
|
+
: 'Fix CRITICAL issues before shipping'
|
|
1647
|
+
};
|
|
1648
|
+
if (args.json)
|
|
1649
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1650
|
+
else {
|
|
1651
|
+
console.log('\nREVIEW Phase');
|
|
1652
|
+
console.log(`\nReview evidence: ${record.id}`);
|
|
1653
|
+
if (reviewHtmlPath)
|
|
1654
|
+
console.log(`HTML report: ${reviewHtmlPath}`);
|
|
1655
|
+
console.log('\nReview Findings:');
|
|
1656
|
+
console.log('----------------------------------------');
|
|
1657
|
+
console.log(`CRITICAL: ${summary.critical} issues ${summary.critical > 0 ? 'BLOCKED' : 'OK'}`);
|
|
1658
|
+
console.log(`HIGH: ${summary.high} issues ${summary.high > 0 ? 'BLOCKED' : 'OK'}`);
|
|
1659
|
+
console.log(`MEDIUM: ${summary.medium} issues`);
|
|
1660
|
+
console.log(`LOW: ${summary.low} issues`);
|
|
1661
|
+
console.log('----------------------------------------');
|
|
1662
|
+
findings.slice(0, 10).forEach(f => console.log(` [${f.severity}] ${f.file ? `${f.file}: ` : ''}${f.description}`));
|
|
1663
|
+
if (passed) {
|
|
1664
|
+
console.log('\nReview passed (no CRITICAL issues)');
|
|
1665
|
+
console.log('\n Next: scale ship ' + (args['task-id'] ?? '<task-id>') + '\n');
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
console.log('\nReview blocked by CRITICAL issues');
|
|
1669
|
+
console.log('\n Fix critical issues, then: scale review\n');
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
},
|
|
1673
|
+
});
|
|
1674
|
+
// SHIP Phase - HonestDelivery
|
|
1675
|
+
export const phaseShip = defineCommand({
|
|
1676
|
+
meta: { name: 'ship', description: 'SHIP: Commit with HonestDelivery Report (/ship)' },
|
|
1677
|
+
args: {
|
|
1678
|
+
'task-id': { type: 'positional', required: true },
|
|
1679
|
+
message: { type: 'string', alias: 'm', description: 'Commit message' },
|
|
1680
|
+
'no-commit': { type: 'boolean', default: false, description: 'Skip git commit' },
|
|
1681
|
+
'skip-commit': { type: 'boolean', default: false, description: 'Skip git commit' },
|
|
1682
|
+
json: { type: 'boolean', default: false },
|
|
1683
|
+
},
|
|
1684
|
+
async run({ args }) {
|
|
1685
|
+
const { store, fsm, workflowEngine } = getEngine();
|
|
1686
|
+
// Validate task exists
|
|
1687
|
+
const task = await store.get(args['task-id']);
|
|
1688
|
+
if (!task || task.type !== 'Task') {
|
|
1689
|
+
console.error(`\nTask not found: ${args['task-id']}\n`);
|
|
1690
|
+
process.exit(1);
|
|
1691
|
+
}
|
|
1692
|
+
// Check if task is completed (or attempt transition)
|
|
1693
|
+
const payload = task.payload;
|
|
1694
|
+
const evidenceValidation = validateVerificationEvidence(payload.verificationEvidenceIds);
|
|
1695
|
+
const reviewValidation = validateReviewEvidence(payload.reviewEvidenceIds);
|
|
1696
|
+
const verificationPassed = payload.buildStatus === 'success' &&
|
|
1697
|
+
(payload.buildExitCode ?? 1) === 0 &&
|
|
1698
|
+
payload.lintStatus === 'success' &&
|
|
1699
|
+
payload.testPassed === true &&
|
|
1700
|
+
(payload.testCoverage ?? 0) >= 80 &&
|
|
1701
|
+
evidenceValidation.ok;
|
|
1702
|
+
const reviewPassed = payload.reviewPassed === true && reviewValidation.ok;
|
|
1703
|
+
const artifactGatePassed = payload.artifactGateMode !== 'block' || payload.artifactGatePassed !== false;
|
|
1704
|
+
const skillGatePassed = payload.skillGatePassed !== false;
|
|
1705
|
+
const toolEvidenceGatePassed = payload.toolEvidenceGatePassed !== false;
|
|
1706
|
+
if (!artifactGatePassed) {
|
|
1707
|
+
console.error('\nTask artifact gate did not pass. Complete required task artifacts and re-run: scale verify ' + args['task-id'] + ' --artifact-gate block\n');
|
|
1708
|
+
if (payload.artifactComplete === false) {
|
|
1709
|
+
console.error('Required task artifacts are incomplete.');
|
|
1710
|
+
}
|
|
1711
|
+
process.exit(1);
|
|
1712
|
+
}
|
|
1713
|
+
if (!skillGatePassed) {
|
|
1714
|
+
console.error('\nTask skill gate did not pass. Complete required skill evidence artifacts and re-run: scale verify ' + args['task-id'] + '\n');
|
|
1715
|
+
process.exit(1);
|
|
1716
|
+
}
|
|
1717
|
+
if (!toolEvidenceGatePassed) {
|
|
1718
|
+
console.error('\nTask tool evidence gate did not pass. Run required tools and re-run: scale verify ' + args['task-id'] + ' --tool-gate ' + (payload.toolOrchestrationMode ?? 'evidence-required') + '\n');
|
|
1719
|
+
if (payload.requiredTools?.length) {
|
|
1720
|
+
console.error('Required tools: ' + payload.requiredTools.join(', '));
|
|
1721
|
+
}
|
|
1722
|
+
process.exit(1);
|
|
1723
|
+
}
|
|
1724
|
+
if (task.status !== 'COMPLETED') {
|
|
1725
|
+
if (!verificationPassed) {
|
|
1726
|
+
console.error('\nTask not verified with persisted evidence. Run: scale verify ' + args['task-id'] + '\n');
|
|
1727
|
+
if (evidenceValidation.missing.length > 0) {
|
|
1728
|
+
console.error('Missing evidence records: ' + evidenceValidation.missing.join(', '));
|
|
1729
|
+
}
|
|
1730
|
+
if (evidenceValidation.failed.length > 0) {
|
|
1731
|
+
console.error('Failed evidence records: ' + evidenceValidation.failed.join(', '));
|
|
1732
|
+
}
|
|
1733
|
+
process.exit(1);
|
|
1734
|
+
}
|
|
1735
|
+
// FSM transition with guard check
|
|
1736
|
+
const completeResult = await fsm.canTransition(args['task-id'], 'complete');
|
|
1737
|
+
if (!completeResult.allowed) {
|
|
1738
|
+
console.error('\nFSM transition blocked: RUNNING -> COMPLETED');
|
|
1739
|
+
completeResult.blockedBy?.forEach(b => console.error(` [GUARD] ${b.guard}: ${b.message}`));
|
|
1740
|
+
console.log('\n Run verification first: scale verify ' + args['task-id'] + '\n');
|
|
1741
|
+
process.exit(1);
|
|
1742
|
+
}
|
|
1743
|
+
await fsm.transition(args['task-id'], 'complete', {
|
|
1744
|
+
actor: { kind: 'human', userId: 'cli' }
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
if (!reviewPassed) {
|
|
1748
|
+
console.error('\nTask not reviewed with persisted passing evidence. Run: scale review ' + args['task-id'] + '\n');
|
|
1749
|
+
if (reviewValidation.missing.length > 0) {
|
|
1750
|
+
console.error('Missing review records: ' + reviewValidation.missing.join(', '));
|
|
1751
|
+
}
|
|
1752
|
+
if (reviewValidation.failed.length > 0) {
|
|
1753
|
+
console.error('Failed review records: ' + reviewValidation.failed.join(', '));
|
|
1754
|
+
}
|
|
1755
|
+
process.exit(1);
|
|
1756
|
+
}
|
|
1757
|
+
// Git operations
|
|
1758
|
+
let commitHash = null;
|
|
1759
|
+
let stagedFiles = [];
|
|
1760
|
+
let workspaceBoundary = null;
|
|
1761
|
+
if (!shouldSkipCommit(args['skip-commit'])) {
|
|
1762
|
+
const commitMessage = args.message ?? `feat: ${task.title ?? args['task-id']}`;
|
|
1763
|
+
try {
|
|
1764
|
+
workspaceBoundary = await validateWorkspaceShipBoundary();
|
|
1765
|
+
if (workspaceBoundary.blockers.length > 0) {
|
|
1766
|
+
console.error('\nWorkspace boundary check failed. Resolve child repositories before shipping the root commit.');
|
|
1767
|
+
workspaceBoundary.blockers.forEach(blocker => console.error(' - ' + blocker));
|
|
1768
|
+
console.error('\nRun scale workspace finish --summary for the shortest fix list, or --json for the full workspace state.\n');
|
|
1769
|
+
process.exit(1);
|
|
1770
|
+
}
|
|
1771
|
+
const reviewRecords = getValidatedReviewRecords(payload.reviewEvidenceIds);
|
|
1772
|
+
const stageResult = await stageReviewedFiles(reviewRecords);
|
|
1773
|
+
if (stageResult.unreviewedFiles.length > 0) {
|
|
1774
|
+
console.error('\nUnreviewed working tree changes detected. Re-run scale review before shipping.');
|
|
1775
|
+
stageResult.unreviewedFiles.forEach(file => console.error(' - ' + file));
|
|
1776
|
+
console.error('\nUse scale ship ' + args['task-id'] + ' --no-commit to generate the delivery report without committing.\n');
|
|
1777
|
+
process.exit(1);
|
|
1778
|
+
}
|
|
1779
|
+
stagedFiles = stageResult.stagedFiles;
|
|
1780
|
+
const result = await runGit(['commit', '-m', commitMessage]);
|
|
1781
|
+
if (result.exitCode !== 0) {
|
|
1782
|
+
const message = result.stderr || result.stdout || 'git commit failed';
|
|
1783
|
+
if (/nothing to commit|no changes added/i.test(message)) {
|
|
1784
|
+
if (!args.json)
|
|
1785
|
+
console.log(' Git commit skipped: nothing to commit');
|
|
1786
|
+
}
|
|
1787
|
+
else {
|
|
1788
|
+
throw new Error(message);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
else {
|
|
1792
|
+
commitHash = result.stdout.split('\n')[0]; // First line contains hash
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
catch (e) {
|
|
1796
|
+
const error = e;
|
|
1797
|
+
console.error('\nGit commit failed:', error.message);
|
|
1798
|
+
process.exit(1);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
// Update Plan to DONE if Task completed
|
|
1802
|
+
if (task.parents.length > 0) {
|
|
1803
|
+
const planId = task.parents[0];
|
|
1804
|
+
try {
|
|
1805
|
+
await fsm.transition(planId, 'complete', { actor: { kind: 'system', component: 'phase-ship' } });
|
|
1806
|
+
}
|
|
1807
|
+
catch (e) {
|
|
1808
|
+
console.error("Warning: Plan completion transition failed:", e.message);
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
// === WorkflowEngine Integration ===
|
|
1812
|
+
// Generate HonestDelivery report
|
|
1813
|
+
if (!args.json) {
|
|
1814
|
+
console.log('\nHonest Delivery Report:');
|
|
1815
|
+
console.log('-'.repeat(40));
|
|
1816
|
+
console.log(`[COMPLETED]`);
|
|
1817
|
+
console.log(` - Task: ${args['task-id']}`);
|
|
1818
|
+
console.log(` - Status: COMPLETED`);
|
|
1819
|
+
if (commitHash)
|
|
1820
|
+
console.log(` - Commit: ${commitHash}`);
|
|
1821
|
+
if (stagedFiles.length)
|
|
1822
|
+
console.log(` - Files committed: ${stagedFiles.length}`);
|
|
1823
|
+
console.log('');
|
|
1824
|
+
console.log(`[VERIFIED]`);
|
|
1825
|
+
console.log(' [PASS] Build: passed');
|
|
1826
|
+
console.log(' [PASS] Lint: passed');
|
|
1827
|
+
console.log(' [PASS] Tests: passed');
|
|
1828
|
+
if (payload.testCoverage)
|
|
1829
|
+
console.log(` [PASS] Coverage: ${payload.testCoverage}%`);
|
|
1830
|
+
if (payload.verificationEvidenceIds?.length) {
|
|
1831
|
+
console.log(` [PASS] Evidence records validated: ${payload.verificationEvidenceIds.join(', ')}`);
|
|
1832
|
+
}
|
|
1833
|
+
if (payload.reviewEvidenceIds?.length) {
|
|
1834
|
+
console.log(` [PASS] Review records validated: ${payload.reviewEvidenceIds.join(', ')}`);
|
|
1835
|
+
}
|
|
1836
|
+
console.log('');
|
|
1837
|
+
// Check for unverified items
|
|
1838
|
+
const unverifiedItems = [];
|
|
1839
|
+
if (!payload.testCoverage || payload.testCoverage < 80) {
|
|
1840
|
+
unverifiedItems.push('Coverage below 80%');
|
|
1841
|
+
}
|
|
1842
|
+
if (unverifiedItems.length > 0) {
|
|
1843
|
+
console.log(`[UNVERIFIED]`);
|
|
1844
|
+
unverifiedItems.forEach(item => console.log(` [UNVERIFIED] ${item}`));
|
|
1845
|
+
console.log('');
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
const result = {
|
|
1849
|
+
phase: 'SHIP',
|
|
1850
|
+
taskId: args['task-id'],
|
|
1851
|
+
status: 'COMPLETED',
|
|
1852
|
+
verificationEvidenceIds: payload.verificationEvidenceIds ?? [],
|
|
1853
|
+
evidenceValidation,
|
|
1854
|
+
reviewEvidenceIds: payload.reviewEvidenceIds ?? [],
|
|
1855
|
+
reviewValidation,
|
|
1856
|
+
commitHash,
|
|
1857
|
+
stagedFiles,
|
|
1858
|
+
workspaceBoundary: workspaceBoundary ? {
|
|
1859
|
+
topology: workspaceBoundary.report?.topology.topology ?? null,
|
|
1860
|
+
configured: workspaceBoundary.report?.topology.configured ?? false,
|
|
1861
|
+
branchPolicy: workspaceBoundary.report?.branchPolicy ?? null,
|
|
1862
|
+
childRepositories: workspaceBoundary.report?.childRepositories.length ?? 0,
|
|
1863
|
+
blockers: workspaceBoundary.blockers,
|
|
1864
|
+
warnings: workspaceBoundary.warnings,
|
|
1865
|
+
} : null,
|
|
1866
|
+
};
|
|
1867
|
+
if (args.json)
|
|
1868
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1869
|
+
else {
|
|
1870
|
+
console.log('\nSHIP Phase');
|
|
1871
|
+
console.log('\nTask COMPLETED: ' + args['task-id']);
|
|
1872
|
+
if (commitHash)
|
|
1873
|
+
console.log(' Commit: ' + commitHash);
|
|
1874
|
+
console.log('\nDone. Feature shipped.\n');
|
|
1875
|
+
}
|
|
1876
|
+
},
|
|
1877
|
+
});
|
|
1878
|
+
//# sourceMappingURL=phaseCommands.js.map
|