@amsterdamdatalabs/enact-operator 0.1.2
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/README.md +33 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lanes/autopilot/index.d.ts +95 -0
- package/dist/lanes/autopilot/index.d.ts.map +1 -0
- package/dist/lanes/autopilot/index.js +499 -0
- package/dist/lanes/autopilot/index.js.map +1 -0
- package/dist/lanes/ralph/index.d.ts +118 -0
- package/dist/lanes/ralph/index.d.ts.map +1 -0
- package/dist/lanes/ralph/index.js +680 -0
- package/dist/lanes/ralph/index.js.map +1 -0
- package/dist/lanes/team/index.d.ts +110 -0
- package/dist/lanes/team/index.d.ts.map +1 -0
- package/dist/lanes/team/index.js +748 -0
- package/dist/lanes/team/index.js.map +1 -0
- package/dist/lanes/team/roles.d.ts +15 -0
- package/dist/lanes/team/roles.d.ts.map +1 -0
- package/dist/lanes/team/roles.js +89 -0
- package/dist/lanes/team/roles.js.map +1 -0
- package/dist/lanes/ultrawork/burst.d.ts +69 -0
- package/dist/lanes/ultrawork/burst.d.ts.map +1 -0
- package/dist/lanes/ultrawork/burst.js +254 -0
- package/dist/lanes/ultrawork/burst.js.map +1 -0
- package/dist/lanes/ultrawork/index.d.ts +159 -0
- package/dist/lanes/ultrawork/index.d.ts.map +1 -0
- package/dist/lanes/ultrawork/index.js +919 -0
- package/dist/lanes/ultrawork/index.js.map +1 -0
- package/dist/lanes/ultrawork/phases.d.ts +57 -0
- package/dist/lanes/ultrawork/phases.d.ts.map +1 -0
- package/dist/lanes/ultrawork/phases.js +116 -0
- package/dist/lanes/ultrawork/phases.js.map +1 -0
- package/dist/mcp/activation.d.ts +5 -0
- package/dist/mcp/activation.d.ts.map +1 -0
- package/dist/mcp/activation.js +234 -0
- package/dist/mcp/activation.js.map +1 -0
- package/dist/mcp/cli.d.ts +11 -0
- package/dist/mcp/cli.d.ts.map +1 -0
- package/dist/mcp/cli.js +140 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/mcp/continuation.d.ts +5 -0
- package/dist/mcp/continuation.d.ts.map +1 -0
- package/dist/mcp/continuation.js +360 -0
- package/dist/mcp/continuation.js.map +1 -0
- package/dist/mcp/jobs.d.ts +5 -0
- package/dist/mcp/jobs.d.ts.map +1 -0
- package/dist/mcp/jobs.js +212 -0
- package/dist/mcp/jobs.js.map +1 -0
- package/dist/mcp/laneSupport.d.ts +19 -0
- package/dist/mcp/laneSupport.d.ts.map +1 -0
- package/dist/mcp/laneSupport.js +21 -0
- package/dist/mcp/laneSupport.js.map +1 -0
- package/dist/mcp/lanes/autopilot.d.ts +5 -0
- package/dist/mcp/lanes/autopilot.d.ts.map +1 -0
- package/dist/mcp/lanes/autopilot.js +227 -0
- package/dist/mcp/lanes/autopilot.js.map +1 -0
- package/dist/mcp/lanes/ralph.d.ts +5 -0
- package/dist/mcp/lanes/ralph.d.ts.map +1 -0
- package/dist/mcp/lanes/ralph.js +392 -0
- package/dist/mcp/lanes/ralph.js.map +1 -0
- package/dist/mcp/lanes/team.d.ts +5 -0
- package/dist/mcp/lanes/team.d.ts.map +1 -0
- package/dist/mcp/lanes/team.js +413 -0
- package/dist/mcp/lanes/team.js.map +1 -0
- package/dist/mcp/lanes/ultrawork.d.ts +5 -0
- package/dist/mcp/lanes/ultrawork.d.ts.map +1 -0
- package/dist/mcp/lanes/ultrawork.js +497 -0
- package/dist/mcp/lanes/ultrawork.js.map +1 -0
- package/dist/mcp/linkage.d.ts +5 -0
- package/dist/mcp/linkage.d.ts.map +1 -0
- package/dist/mcp/linkage.js +126 -0
- package/dist/mcp/linkage.js.map +1 -0
- package/dist/mcp/planning.d.ts +5 -0
- package/dist/mcp/planning.d.ts.map +1 -0
- package/dist/mcp/planning.js +584 -0
- package/dist/mcp/planning.js.map +1 -0
- package/dist/mcp/rpcTransport.d.ts +17 -0
- package/dist/mcp/rpcTransport.d.ts.map +1 -0
- package/dist/mcp/rpcTransport.js +90 -0
- package/dist/mcp/rpcTransport.js.map +1 -0
- package/dist/mcp/schemas/ralphVerify.d.ts +32 -0
- package/dist/mcp/schemas/ralphVerify.d.ts.map +1 -0
- package/dist/mcp/schemas/ralphVerify.js +20 -0
- package/dist/mcp/schemas/ralphVerify.js.map +1 -0
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +176 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/system.d.ts +5 -0
- package/dist/mcp/system.d.ts.map +1 -0
- package/dist/mcp/system.js +445 -0
- package/dist/mcp/system.js.map +1 -0
- package/dist/mcp/toolFilter.d.ts +2 -0
- package/dist/mcp/toolFilter.d.ts.map +1 -0
- package/dist/mcp/toolFilter.js +2 -0
- package/dist/mcp/toolFilter.js.map +1 -0
- package/dist/mcp/toolPartitions.d.ts +20 -0
- package/dist/mcp/toolPartitions.d.ts.map +1 -0
- package/dist/mcp/toolPartitions.js +280 -0
- package/dist/mcp/toolPartitions.js.map +1 -0
- package/dist/mcp/toolRuntime.d.ts +9 -0
- package/dist/mcp/toolRuntime.d.ts.map +1 -0
- package/dist/mcp/toolRuntime.js +179 -0
- package/dist/mcp/toolRuntime.js.map +1 -0
- package/dist/mcp/workflow.d.ts +12 -0
- package/dist/mcp/workflow.d.ts.map +1 -0
- package/dist/mcp/workflow.js +723 -0
- package/dist/mcp/workflow.js.map +1 -0
- package/dist/operator/hooks/hookDispatcher.d.ts +39 -0
- package/dist/operator/hooks/hookDispatcher.d.ts.map +1 -0
- package/dist/operator/hooks/hookDispatcher.js +58 -0
- package/dist/operator/hooks/hookDispatcher.js.map +1 -0
- package/dist/operator/hooks/hookGating.d.ts +28 -0
- package/dist/operator/hooks/hookGating.d.ts.map +1 -0
- package/dist/operator/hooks/hookGating.js +61 -0
- package/dist/operator/hooks/hookGating.js.map +1 -0
- package/dist/operator/hooks/hooks.d.ts +20 -0
- package/dist/operator/hooks/hooks.d.ts.map +1 -0
- package/dist/operator/hooks/hooks.js +124 -0
- package/dist/operator/hooks/hooks.js.map +1 -0
- package/dist/operator/hooks/toolGuardHooks.d.ts +86 -0
- package/dist/operator/hooks/toolGuardHooks.d.ts.map +1 -0
- package/dist/operator/hooks/toolGuardHooks.js +163 -0
- package/dist/operator/hooks/toolGuardHooks.js.map +1 -0
- package/dist/operator/hud.d.ts +115 -0
- package/dist/operator/hud.d.ts.map +1 -0
- package/dist/operator/hud.js +229 -0
- package/dist/operator/hud.js.map +1 -0
- package/dist/operator/missions.d.ts +125 -0
- package/dist/operator/missions.d.ts.map +1 -0
- package/dist/operator/missions.js +304 -0
- package/dist/operator/missions.js.map +1 -0
- package/dist/operator/operatorCore.d.ts +11 -0
- package/dist/operator/operatorCore.d.ts.map +1 -0
- package/dist/operator/operatorCore.js +9 -0
- package/dist/operator/operatorCore.js.map +1 -0
- package/dist/operator/operatorRuntimeCore.d.ts +17 -0
- package/dist/operator/operatorRuntimeCore.d.ts.map +1 -0
- package/dist/operator/operatorRuntimeCore.js +17 -0
- package/dist/operator/operatorRuntimeCore.js.map +1 -0
- package/dist/operator/runtime.d.ts +74 -0
- package/dist/operator/runtime.d.ts.map +1 -0
- package/dist/operator/runtime.js +357 -0
- package/dist/operator/runtime.js.map +1 -0
- package/dist/shared/core/bootstrap.d.ts +16 -0
- package/dist/shared/core/bootstrap.d.ts.map +1 -0
- package/dist/shared/core/bootstrap.js +77 -0
- package/dist/shared/core/bootstrap.js.map +1 -0
- package/dist/shared/core/contract.d.ts +71 -0
- package/dist/shared/core/contract.d.ts.map +1 -0
- package/dist/shared/core/contract.js +452 -0
- package/dist/shared/core/contract.js.map +1 -0
- package/dist/shared/core/events.d.ts +57 -0
- package/dist/shared/core/events.d.ts.map +1 -0
- package/dist/shared/core/events.js +36 -0
- package/dist/shared/core/events.js.map +1 -0
- package/dist/shared/core/jobs.d.ts +46 -0
- package/dist/shared/core/jobs.d.ts.map +1 -0
- package/dist/shared/core/jobs.js +137 -0
- package/dist/shared/core/jobs.js.map +1 -0
- package/dist/shared/core/json.d.ts +12 -0
- package/dist/shared/core/json.d.ts.map +1 -0
- package/dist/shared/core/json.js +52 -0
- package/dist/shared/core/json.js.map +1 -0
- package/dist/shared/core/layoutMigration.d.ts +11 -0
- package/dist/shared/core/layoutMigration.d.ts.map +1 -0
- package/dist/shared/core/layoutMigration.js +56 -0
- package/dist/shared/core/layoutMigration.js.map +1 -0
- package/dist/shared/core/lifecycle.d.ts +61 -0
- package/dist/shared/core/lifecycle.d.ts.map +1 -0
- package/dist/shared/core/lifecycle.js +123 -0
- package/dist/shared/core/lifecycle.js.map +1 -0
- package/dist/shared/core/packagePaths.d.ts +2 -0
- package/dist/shared/core/packagePaths.d.ts.map +1 -0
- package/dist/shared/core/packagePaths.js +9 -0
- package/dist/shared/core/packagePaths.js.map +1 -0
- package/dist/shared/core/terminology.d.ts +38 -0
- package/dist/shared/core/terminology.d.ts.map +1 -0
- package/dist/shared/core/terminology.js +54 -0
- package/dist/shared/core/terminology.js.map +1 -0
- package/dist/shared/core/types.d.ts +30 -0
- package/dist/shared/core/types.d.ts.map +1 -0
- package/dist/shared/core/types.js +2 -0
- package/dist/shared/core/types.js.map +1 -0
- package/dist/shared/diagnostics/doctor.d.ts +19 -0
- package/dist/shared/diagnostics/doctor.d.ts.map +1 -0
- package/dist/shared/diagnostics/doctor.js +82 -0
- package/dist/shared/diagnostics/doctor.js.map +1 -0
- package/dist/shared/diagnostics/hostRollout.d.ts +16 -0
- package/dist/shared/diagnostics/hostRollout.d.ts.map +1 -0
- package/dist/shared/diagnostics/hostRollout.js +78 -0
- package/dist/shared/diagnostics/hostRollout.js.map +1 -0
- package/dist/shared/observability/emit.d.ts +3 -0
- package/dist/shared/observability/emit.d.ts.map +1 -0
- package/dist/shared/observability/emit.js +17 -0
- package/dist/shared/observability/emit.js.map +1 -0
- package/dist/shared/observability/testWorkspace.d.ts +4 -0
- package/dist/shared/observability/testWorkspace.d.ts.map +1 -0
- package/dist/shared/observability/testWorkspace.js +35 -0
- package/dist/shared/observability/testWorkspace.js.map +1 -0
- package/dist/shared/state/installRegistry.d.ts +22 -0
- package/dist/shared/state/installRegistry.d.ts.map +1 -0
- package/dist/shared/state/installRegistry.js +51 -0
- package/dist/shared/state/installRegistry.js.map +1 -0
- package/dist/shared/state/session.d.ts +18 -0
- package/dist/shared/state/session.d.ts.map +1 -0
- package/dist/shared/state/session.js +127 -0
- package/dist/shared/state/session.js.map +1 -0
- package/dist/shared/state/state.d.ts +16 -0
- package/dist/shared/state/state.d.ts.map +1 -0
- package/dist/shared/state/state.js +91 -0
- package/dist/shared/state/state.js.map +1 -0
- package/dist/shared/state/tasks.d.ts +113 -0
- package/dist/shared/state/tasks.d.ts.map +1 -0
- package/dist/shared/state/tasks.js +274 -0
- package/dist/shared/state/tasks.js.map +1 -0
- package/dist/shared/workflow/activation/activeSkill.d.ts +46 -0
- package/dist/shared/workflow/activation/activeSkill.d.ts.map +1 -0
- package/dist/shared/workflow/activation/activeSkill.js +158 -0
- package/dist/shared/workflow/activation/activeSkill.js.map +1 -0
- package/dist/shared/workflow/activation/gateProfiles.d.ts +26 -0
- package/dist/shared/workflow/activation/gateProfiles.d.ts.map +1 -0
- package/dist/shared/workflow/activation/gateProfiles.js +102 -0
- package/dist/shared/workflow/activation/gateProfiles.js.map +1 -0
- package/dist/shared/workflow/activation/modeMatrix.d.ts +28 -0
- package/dist/shared/workflow/activation/modeMatrix.d.ts.map +1 -0
- package/dist/shared/workflow/activation/modeMatrix.js +91 -0
- package/dist/shared/workflow/activation/modeMatrix.js.map +1 -0
- package/dist/shared/workflow/activation/skillActivation.d.ts +74 -0
- package/dist/shared/workflow/activation/skillActivation.d.ts.map +1 -0
- package/dist/shared/workflow/activation/skillActivation.js +485 -0
- package/dist/shared/workflow/activation/skillActivation.js.map +1 -0
- package/dist/shared/workflow/activation/skillVariant.d.ts +18 -0
- package/dist/shared/workflow/activation/skillVariant.d.ts.map +1 -0
- package/dist/shared/workflow/activation/skillVariant.js +44 -0
- package/dist/shared/workflow/activation/skillVariant.js.map +1 -0
- package/dist/shared/workflow/authority/authority.d.ts +34 -0
- package/dist/shared/workflow/authority/authority.d.ts.map +1 -0
- package/dist/shared/workflow/authority/authority.js +64 -0
- package/dist/shared/workflow/authority/authority.js.map +1 -0
- package/dist/shared/workflow/closure/closureManifest.d.ts +39 -0
- package/dist/shared/workflow/closure/closureManifest.d.ts.map +1 -0
- package/dist/shared/workflow/closure/closureManifest.js +62 -0
- package/dist/shared/workflow/closure/closureManifest.js.map +1 -0
- package/dist/shared/workflow/closure/closureRequirements.d.ts +12 -0
- package/dist/shared/workflow/closure/closureRequirements.d.ts.map +1 -0
- package/dist/shared/workflow/closure/closureRequirements.js +30 -0
- package/dist/shared/workflow/closure/closureRequirements.js.map +1 -0
- package/dist/shared/workflow/closure/contractParity.d.ts +24 -0
- package/dist/shared/workflow/closure/contractParity.d.ts.map +1 -0
- package/dist/shared/workflow/closure/contractParity.js +238 -0
- package/dist/shared/workflow/closure/contractParity.js.map +1 -0
- package/dist/shared/workflow/closure/contractParityContext.d.ts +8 -0
- package/dist/shared/workflow/closure/contractParityContext.d.ts.map +1 -0
- package/dist/shared/workflow/closure/contractParityContext.js +50 -0
- package/dist/shared/workflow/closure/contractParityContext.js.map +1 -0
- package/dist/shared/workflow/closure/scopeGuard.d.ts +11 -0
- package/dist/shared/workflow/closure/scopeGuard.d.ts.map +1 -0
- package/dist/shared/workflow/closure/scopeGuard.js +69 -0
- package/dist/shared/workflow/closure/scopeGuard.js.map +1 -0
- package/dist/shared/workflow/closure/ultragoalArtifact.d.ts +13 -0
- package/dist/shared/workflow/closure/ultragoalArtifact.d.ts.map +1 -0
- package/dist/shared/workflow/closure/ultragoalArtifact.js +31 -0
- package/dist/shared/workflow/closure/ultragoalArtifact.js.map +1 -0
- package/dist/shared/workflow/closure/workflowReconcile.d.ts +70 -0
- package/dist/shared/workflow/closure/workflowReconcile.d.ts.map +1 -0
- package/dist/shared/workflow/closure/workflowReconcile.js +267 -0
- package/dist/shared/workflow/closure/workflowReconcile.js.map +1 -0
- package/dist/shared/workflow/continuation/continuation.d.ts +109 -0
- package/dist/shared/workflow/continuation/continuation.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/continuation.js +550 -0
- package/dist/shared/workflow/continuation/continuation.js.map +1 -0
- package/dist/shared/workflow/continuation/continuationEventReservations.d.ts +17 -0
- package/dist/shared/workflow/continuation/continuationEventReservations.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/continuationEventReservations.js +88 -0
- package/dist/shared/workflow/continuation/continuationEventReservations.js.map +1 -0
- package/dist/shared/workflow/continuation/continuationFollowUp.d.ts +114 -0
- package/dist/shared/workflow/continuation/continuationFollowUp.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/continuationFollowUp.js +330 -0
- package/dist/shared/workflow/continuation/continuationFollowUp.js.map +1 -0
- package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts +66 -0
- package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/continuationOrchestrator.js +144 -0
- package/dist/shared/workflow/continuation/continuationOrchestrator.js.map +1 -0
- package/dist/shared/workflow/continuation/hookContinuation.d.ts +44 -0
- package/dist/shared/workflow/continuation/hookContinuation.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/hookContinuation.js +85 -0
- package/dist/shared/workflow/continuation/hookContinuation.js.map +1 -0
- package/dist/shared/workflow/continuation/stopPolicy.d.ts +38 -0
- package/dist/shared/workflow/continuation/stopPolicy.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/stopPolicy.js +435 -0
- package/dist/shared/workflow/continuation/stopPolicy.js.map +1 -0
- package/dist/shared/workflow/continuation/stopVerdict.d.ts +31 -0
- package/dist/shared/workflow/continuation/stopVerdict.d.ts.map +1 -0
- package/dist/shared/workflow/continuation/stopVerdict.js +98 -0
- package/dist/shared/workflow/continuation/stopVerdict.js.map +1 -0
- package/dist/shared/workflow/delegation/delegatedSession.d.ts +118 -0
- package/dist/shared/workflow/delegation/delegatedSession.d.ts.map +1 -0
- package/dist/shared/workflow/delegation/delegatedSession.js +496 -0
- package/dist/shared/workflow/delegation/delegatedSession.js.map +1 -0
- package/dist/shared/workflow/delegation/delegationPrompt.d.ts +3 -0
- package/dist/shared/workflow/delegation/delegationPrompt.d.ts.map +1 -0
- package/dist/shared/workflow/delegation/delegationPrompt.js +15 -0
- package/dist/shared/workflow/delegation/delegationPrompt.js.map +1 -0
- package/dist/shared/workflow/delegation/sessionTasks.d.ts +40 -0
- package/dist/shared/workflow/delegation/sessionTasks.d.ts.map +1 -0
- package/dist/shared/workflow/delegation/sessionTasks.js +73 -0
- package/dist/shared/workflow/delegation/sessionTasks.js.map +1 -0
- package/dist/shared/workflow/delegation/subagentRuntime.d.ts +26 -0
- package/dist/shared/workflow/delegation/subagentRuntime.d.ts.map +1 -0
- package/dist/shared/workflow/delegation/subagentRuntime.js +231 -0
- package/dist/shared/workflow/delegation/subagentRuntime.js.map +1 -0
- package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts +79 -0
- package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts.map +1 -0
- package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js +166 -0
- package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js.map +1 -0
- package/dist/shared/workflow/delivery/finalWave.d.ts +57 -0
- package/dist/shared/workflow/delivery/finalWave.d.ts.map +1 -0
- package/dist/shared/workflow/delivery/finalWave.js +123 -0
- package/dist/shared/workflow/delivery/finalWave.js.map +1 -0
- package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts +68 -0
- package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts.map +1 -0
- package/dist/shared/workflow/delivery/lifecyclePushMap.js +82 -0
- package/dist/shared/workflow/delivery/lifecyclePushMap.js.map +1 -0
- package/dist/shared/workflow/delivery/prSidecar.d.ts +7 -0
- package/dist/shared/workflow/delivery/prSidecar.d.ts.map +1 -0
- package/dist/shared/workflow/delivery/prSidecar.js +4 -0
- package/dist/shared/workflow/delivery/prSidecar.js.map +1 -0
- package/dist/shared/workflow/delivery/reviewStaleness.d.ts +37 -0
- package/dist/shared/workflow/delivery/reviewStaleness.d.ts.map +1 -0
- package/dist/shared/workflow/delivery/reviewStaleness.js +94 -0
- package/dist/shared/workflow/delivery/reviewStaleness.js.map +1 -0
- package/dist/shared/workflow/planning/hyperplan.d.ts +40 -0
- package/dist/shared/workflow/planning/hyperplan.d.ts.map +1 -0
- package/dist/shared/workflow/planning/hyperplan.js +133 -0
- package/dist/shared/workflow/planning/hyperplan.js.map +1 -0
- package/dist/shared/workflow/planning/notepad.d.ts +17 -0
- package/dist/shared/workflow/planning/notepad.d.ts.map +1 -0
- package/dist/shared/workflow/planning/notepad.js +84 -0
- package/dist/shared/workflow/planning/notepad.js.map +1 -0
- package/dist/shared/workflow/planning/planFormat.d.ts +3 -0
- package/dist/shared/workflow/planning/planFormat.d.ts.map +1 -0
- package/dist/shared/workflow/planning/planFormat.js +14 -0
- package/dist/shared/workflow/planning/planFormat.js.map +1 -0
- package/package.json +155 -0
- package/runtime/hooks/_continuation.mjs +2 -0
- package/runtime/hooks/_lib.mjs +2 -0
- package/runtime/hooks/_toolGuards.mjs +2 -0
- package/runtime/hooks/lanes/resolveSkillActivation.mjs +241 -0
- package/runtime/hooks/lanes/user-prompt-submit.mjs +326 -0
- package/runtime/hooks/layout-dir.mjs +2 -0
- package/runtime/hooks/lifecycle/pre-compact.mjs +121 -0
- package/runtime/hooks/lifecycle/session-start.mjs +356 -0
- package/runtime/hooks/lifecycle/stop.mjs +223 -0
- package/runtime/hooks/observability.mjs +2 -0
- package/runtime/hooks/post-tool-use-failure.mjs +5 -0
- package/runtime/hooks/post-tool-use.mjs +4 -0
- package/runtime/hooks/pre-compact.mjs +4 -0
- package/runtime/hooks/pre-tool-use.mjs +4 -0
- package/runtime/hooks/resolveSkillActivation.mjs +4 -0
- package/runtime/hooks/root-dir.mjs +2 -0
- package/runtime/hooks/session-start.mjs +4 -0
- package/runtime/hooks/shared/_continuation.mjs +341 -0
- package/runtime/hooks/shared/_lib.mjs +60 -0
- package/runtime/hooks/shared/_toolGuards.mjs +237 -0
- package/runtime/hooks/shared/config.mjs +143 -0
- package/runtime/hooks/shared/layout-dir.mjs +12 -0
- package/runtime/hooks/shared/observability.mjs +257 -0
- package/runtime/hooks/shared/root-dir.mjs +9 -0
- package/runtime/hooks/stop.mjs +4 -0
- package/runtime/hooks/subagent-tracker.mjs +4 -0
- package/runtime/hooks/subagents/subagent-tracker.mjs +106 -0
- package/runtime/hooks/tools/post-tool-use-failure.mjs +251 -0
- package/runtime/hooks/tools/post-tool-use.mjs +205 -0
- package/runtime/hooks/tools/pre-tool-use.mjs +268 -0
- package/runtime/hooks/user-prompt-submit.mjs +4 -0
|
@@ -0,0 +1,723 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { ensureLayout, inboxFile, installRegistryFile, LAYOUT_DIRS, layoutDir, layoutPath, ledgerFile, metricsFile, reviewsFile, tasksFile, } from '../shared/core/contract.js';
|
|
4
|
+
import { createEvidenceHorizon } from '../shared/core/events.js';
|
|
5
|
+
import { listJobs } from '../shared/core/jobs.js';
|
|
6
|
+
import { defaultClosureScope } from '../shared/workflow/closure/closureManifest.js';
|
|
7
|
+
import { runContractParity } from '../shared/workflow/closure/contractParity.js';
|
|
8
|
+
import { reconcileWorkflowState, DEFAULT_REVIEW_STALE_MS } from '../shared/workflow/closure/workflowReconcile.js';
|
|
9
|
+
import { readContinuationState, readLogicalIdleStatus } from '../shared/workflow/continuation/continuation.js';
|
|
10
|
+
import { computeReviewStaleState } from '../shared/workflow/delivery/reviewStaleness.js';
|
|
11
|
+
import { evaluateStopPolicy } from '../shared/workflow/continuation/stopPolicy.js';
|
|
12
|
+
import { readOperatorAuthority } from '../shared/workflow/authority/authority.js';
|
|
13
|
+
import { normalizeOperatorGoal } from '../shared/workflow/activation/skillActivation.js';
|
|
14
|
+
import { getRalph } from '../lanes/ralph/index.js';
|
|
15
|
+
import { buildUltraworkPhaseContext, getUltrawork, linkTaskRef } from '../lanes/ultrawork/index.js';
|
|
16
|
+
import { inferUltraworkPhase } from '../lanes/ultrawork/phases.js';
|
|
17
|
+
import { appendLedger, listInbox, listLedger, listReviews, updateReview } from '../operator/runtime.js';
|
|
18
|
+
import { applyConvergedReviewFilter, computeStaleCounts } from '../operator/hud.js';
|
|
19
|
+
import { readSession } from '../shared/state/session.js';
|
|
20
|
+
import { readTeam } from '../lanes/team/index.js';
|
|
21
|
+
import { createTask, getTask, listTasks, updateTask } from '../shared/state/tasks.js';
|
|
22
|
+
import { handled, requiredString, UNHANDLED } from '../mcp/laneSupport.js';
|
|
23
|
+
import { ultraworkToolDefinitions } from '../mcp/lanes/ultrawork.js';
|
|
24
|
+
export const SNAPSHOT_RECENT_OPEN_LIMIT = 5;
|
|
25
|
+
export const SNAPSHOT_RECENT_REVIEW_LIMIT = 10;
|
|
26
|
+
export const SNAPSHOT_FIELDS = [
|
|
27
|
+
'view',
|
|
28
|
+
'staleCounts',
|
|
29
|
+
'session',
|
|
30
|
+
'autopilot',
|
|
31
|
+
'ultrawork',
|
|
32
|
+
'ralph',
|
|
33
|
+
'activeSkill',
|
|
34
|
+
'inbox',
|
|
35
|
+
'activeTasks',
|
|
36
|
+
'team',
|
|
37
|
+
'recentReviews',
|
|
38
|
+
'goalScope',
|
|
39
|
+
'unresolvedContractGaps',
|
|
40
|
+
'stopSafety',
|
|
41
|
+
'activeJobs',
|
|
42
|
+
'continuation',
|
|
43
|
+
'logicalIdle',
|
|
44
|
+
];
|
|
45
|
+
export function asSnapshotFieldSet() {
|
|
46
|
+
return new Set(SNAPSHOT_FIELDS);
|
|
47
|
+
}
|
|
48
|
+
export function activeGoalForMode(mode, ralph, ultrawork) {
|
|
49
|
+
if (mode === 'ralph') {
|
|
50
|
+
return ralph?.active ? ralph.goal : null;
|
|
51
|
+
}
|
|
52
|
+
return ultrawork?.active ? ultrawork.intent : null;
|
|
53
|
+
}
|
|
54
|
+
function snapshotPaths(root) {
|
|
55
|
+
const base = layoutDir(root);
|
|
56
|
+
const dirs = LAYOUT_DIRS.map((dirName) => layoutPath(root, dirName));
|
|
57
|
+
const seeds = [
|
|
58
|
+
tasksFile(root),
|
|
59
|
+
reviewsFile(root),
|
|
60
|
+
inboxFile(root),
|
|
61
|
+
ledgerFile(root),
|
|
62
|
+
installRegistryFile(root),
|
|
63
|
+
metricsFile(root),
|
|
64
|
+
];
|
|
65
|
+
return [base, ...dirs, ...seeds].filter((path) => existsSync(path));
|
|
66
|
+
}
|
|
67
|
+
function collectBootstrapValidationErrors(root) {
|
|
68
|
+
const errors = [];
|
|
69
|
+
const validators = [
|
|
70
|
+
['state/tasks.json', () => listTasks(root)],
|
|
71
|
+
['state/reviews.json', () => listReviews(root)],
|
|
72
|
+
['state/inbox.json', () => listInbox(root)],
|
|
73
|
+
['logs/ledger.json', () => listLedger(root, 1)],
|
|
74
|
+
['sessions/current.json', () => readSession(root)],
|
|
75
|
+
['state/ralph.json', () => getRalph(root)],
|
|
76
|
+
['state/ultrawork.json', () => getUltrawork(root)],
|
|
77
|
+
['team/team.json', () => readTeam(root)],
|
|
78
|
+
];
|
|
79
|
+
for (const [label, validate] of validators) {
|
|
80
|
+
try {
|
|
81
|
+
validate();
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
errors.push(`${label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return errors;
|
|
88
|
+
}
|
|
89
|
+
function bootstrapStatus(root) {
|
|
90
|
+
const dirPresent = [];
|
|
91
|
+
const dirMissing = [];
|
|
92
|
+
for (const dirName of LAYOUT_DIRS) {
|
|
93
|
+
const path = layoutPath(root, dirName);
|
|
94
|
+
(existsSync(path) ? dirPresent : dirMissing).push(dirName);
|
|
95
|
+
}
|
|
96
|
+
const seedEntries = [
|
|
97
|
+
['state/tasks.json', tasksFile(root)],
|
|
98
|
+
['state/reviews.json', reviewsFile(root)],
|
|
99
|
+
['state/inbox.json', inboxFile(root)],
|
|
100
|
+
['logs/ledger.json', ledgerFile(root)],
|
|
101
|
+
['state/install-registry.json', installRegistryFile(root)],
|
|
102
|
+
['metrics.json', metricsFile(root)],
|
|
103
|
+
];
|
|
104
|
+
const seedPresent = [];
|
|
105
|
+
const seedMissing = [];
|
|
106
|
+
for (const [label, path] of seedEntries) {
|
|
107
|
+
(existsSync(path) ? seedPresent : seedMissing).push(label);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
present: dirPresent,
|
|
111
|
+
missing: dirMissing,
|
|
112
|
+
totalRequired: LAYOUT_DIRS.length,
|
|
113
|
+
seedFiles: { present: seedPresent, missing: seedMissing },
|
|
114
|
+
validationErrors: collectBootstrapValidationErrors(root),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function composeOperatorSnapshot(authority, view = 'converged') {
|
|
118
|
+
const { session, autopilot, ralph, ultrawork, team, tasks: allTasks, reviews: allReviews, inbox, operatorActive } = authority;
|
|
119
|
+
const openItems = inbox.filter((item) => item.status === 'open');
|
|
120
|
+
const recentOpen = openItems
|
|
121
|
+
.slice()
|
|
122
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
|
123
|
+
.slice(0, SNAPSHOT_RECENT_OPEN_LIMIT);
|
|
124
|
+
const activeTasks = allTasks.filter((task) => task.status === 'pending' || task.status === 'queued' || task.status === 'in_progress' || task.status === 'review');
|
|
125
|
+
const filteredReviews = view === 'converged'
|
|
126
|
+
? applyConvergedReviewFilter(allReviews)
|
|
127
|
+
: allReviews;
|
|
128
|
+
const recentReviews = filteredReviews
|
|
129
|
+
.slice()
|
|
130
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
|
131
|
+
.slice(0, SNAPSHOT_RECENT_REVIEW_LIMIT);
|
|
132
|
+
const goalScope = autopilot?.goalScope ??
|
|
133
|
+
ralph?.goalScope ??
|
|
134
|
+
ultrawork?.goalScope ??
|
|
135
|
+
null;
|
|
136
|
+
const staleCounts = computeStaleCounts(allReviews, listTasks(authority.root));
|
|
137
|
+
const continuation = readContinuationState(authority.root);
|
|
138
|
+
const logicalIdle = readLogicalIdleStatus(authority.root);
|
|
139
|
+
let phaseStale = false;
|
|
140
|
+
if (ultrawork && ultrawork.active) {
|
|
141
|
+
const phaseContext = buildUltraworkPhaseContext(ultrawork, allReviews, authority.root);
|
|
142
|
+
const phaseInference = inferUltraworkPhase(phaseContext);
|
|
143
|
+
phaseStale = phaseInference.inferredPhase !== null
|
|
144
|
+
&& phaseInference.inferredPhase !== ultrawork.phase
|
|
145
|
+
&& !phaseInference.blockedByTransitionGuard;
|
|
146
|
+
}
|
|
147
|
+
const allJobs = listJobs(authority.root);
|
|
148
|
+
const scheduledJobs = allJobs.filter((job) => job.status === 'scheduled');
|
|
149
|
+
const pausedJobs = allJobs.filter((job) => job.status === 'paused');
|
|
150
|
+
const monitorJobs = allJobs.filter((job) => job.kind === 'monitor' && job.status === 'scheduled');
|
|
151
|
+
const nextFireAt = scheduledJobs
|
|
152
|
+
.filter((job) => job.scheduledFor !== undefined)
|
|
153
|
+
.map((job) => job.scheduledFor)
|
|
154
|
+
.sort()[0];
|
|
155
|
+
const linkedJobsForLane = (laneId) => {
|
|
156
|
+
if (!laneId)
|
|
157
|
+
return [];
|
|
158
|
+
return allJobs.filter((job) => job.status !== 'cancelled'
|
|
159
|
+
&& job.linkage
|
|
160
|
+
&& (job.linkage.modeId === laneId || job.linkage.taskId === laneId));
|
|
161
|
+
};
|
|
162
|
+
const autopilotWithJobs = autopilot ? { ...autopilot, linkedJobs: linkedJobsForLane(autopilot.id) } : autopilot;
|
|
163
|
+
const ralphWithJobs = ralph ? { ...ralph, linkedJobs: linkedJobsForLane(ralph.id) } : ralph;
|
|
164
|
+
const ultraworkWithJobs = ultrawork ? { ...ultrawork, linkedJobs: linkedJobsForLane(ultrawork.id) } : ultrawork;
|
|
165
|
+
return {
|
|
166
|
+
view,
|
|
167
|
+
staleCounts,
|
|
168
|
+
session,
|
|
169
|
+
autopilot: autopilotWithJobs,
|
|
170
|
+
ultrawork: ultraworkWithJobs,
|
|
171
|
+
ralph: ralphWithJobs,
|
|
172
|
+
activeOperator: operatorActive,
|
|
173
|
+
inbox: { open: openItems.length, total: inbox.length, recentOpen },
|
|
174
|
+
activeTasks,
|
|
175
|
+
team,
|
|
176
|
+
recentReviews,
|
|
177
|
+
goalScope,
|
|
178
|
+
unresolvedContractGaps: [],
|
|
179
|
+
phaseStale,
|
|
180
|
+
activeJobs: {
|
|
181
|
+
scheduled: scheduledJobs.length,
|
|
182
|
+
paused: pausedJobs.length,
|
|
183
|
+
monitors: monitorJobs.length,
|
|
184
|
+
nextFireAt,
|
|
185
|
+
},
|
|
186
|
+
continuation,
|
|
187
|
+
logicalIdle,
|
|
188
|
+
stopSafety: (() => {
|
|
189
|
+
const verdict = evaluateStopPolicy({ authority, root: authority.root });
|
|
190
|
+
return {
|
|
191
|
+
outcome: verdict.outcome,
|
|
192
|
+
reasons: verdict.reasons,
|
|
193
|
+
transportCanBlock: verdict.transportCanBlock,
|
|
194
|
+
};
|
|
195
|
+
})(),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export const workflowToolDefinitions = [
|
|
199
|
+
{
|
|
200
|
+
name: 'operator_workflow_reconcile',
|
|
201
|
+
description: 'Classify stale workflow state in tasks/reviews and optionally stamp additive metadata hints. Does not delete records or advance phases.',
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: 'object',
|
|
204
|
+
properties: {
|
|
205
|
+
root: { type: 'string' },
|
|
206
|
+
apply: {
|
|
207
|
+
type: 'boolean',
|
|
208
|
+
description: 'Apply additive metadata updates (reviewStale/task.reviewStale) for detected stale pairs.',
|
|
209
|
+
},
|
|
210
|
+
staleReviewAgeMs: {
|
|
211
|
+
type: 'number',
|
|
212
|
+
description: `If a pending review is this many milliseconds old, classify as stale. Defaults to ${DEFAULT_REVIEW_STALE_MS}.`,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'operator_resume_from_repo_truth',
|
|
219
|
+
description: 'D8 re-open helper: refresh stale flags via reconcile, then compose D4/D5 recompute if those tools are present. Returns consolidated { reconciled, recomputed, reassessed, suggestedNextActions[] }. Does NOT advance any state beyond what D4 already permits.',
|
|
220
|
+
inputSchema: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: {
|
|
223
|
+
root: { type: 'string' },
|
|
224
|
+
modeType: { type: 'string', enum: ['ralph', 'ultrawork', 'autopilot'], description: 'Runtime mode type.' },
|
|
225
|
+
modeId: { type: 'string', description: 'Optional mode id; if omitted reads current session.' },
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: 'operator_review_refresh',
|
|
231
|
+
description: 'D8 re-open helper: re-run computeReviewStaleState for one review against the current ledger verification runs and update staleState/supersededBy if changed. Returns { before, after, changed }.',
|
|
232
|
+
inputSchema: {
|
|
233
|
+
type: 'object',
|
|
234
|
+
properties: {
|
|
235
|
+
root: { type: 'string' },
|
|
236
|
+
reviewId: { type: 'string', description: 'The review id to refresh.' },
|
|
237
|
+
},
|
|
238
|
+
required: ['reviewId'],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'operator_task_reconcile',
|
|
243
|
+
description: 'D8 re-open helper: for a single runtime task (task), recompute reviewStale, blockerStale, evidenceOutdated from current ledger/repo truth and update additive companion metadata in place. Returns the delta.',
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: 'object',
|
|
246
|
+
properties: {
|
|
247
|
+
root: { type: 'string' },
|
|
248
|
+
taskId: { type: 'string', description: 'The local task id (runtime tool-id vocabulary).' },
|
|
249
|
+
},
|
|
250
|
+
required: ['taskId'],
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'operator_runtime_bootstrap_status',
|
|
255
|
+
description: 'Read-only check of the Operator runtime layout. Returns which required directories and seeded JSON files are present or missing under the .enact/operator tree.',
|
|
256
|
+
inputSchema: {
|
|
257
|
+
type: 'object',
|
|
258
|
+
properties: {
|
|
259
|
+
root: { type: 'string' },
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: 'operator_runtime_bootstrap_repair',
|
|
265
|
+
description: 'Ensure the Operator runtime layout exists by calling ensureLayout, then return a status report plus a list of directories and files that were created.',
|
|
266
|
+
inputSchema: {
|
|
267
|
+
type: 'object',
|
|
268
|
+
properties: {
|
|
269
|
+
root: { type: 'string' },
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: 'operator_contract_parity_run',
|
|
275
|
+
description: 'Run the contract-parity gate for a lane tracker id. Reads closure criteria from .enact/operator/manifest.yaml only. Fails in strict mode if no declarative source exists.',
|
|
276
|
+
inputSchema: {
|
|
277
|
+
type: 'object',
|
|
278
|
+
properties: {
|
|
279
|
+
root: { type: 'string' },
|
|
280
|
+
taskId: { type: 'string' },
|
|
281
|
+
},
|
|
282
|
+
required: ['taskId'],
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: 'operator_task_create_closure_pass',
|
|
287
|
+
description: 'Creates a closure-pass task linked to the active Ultrawork session. Computes write-scope union across linked tasks and assigns closureScope of "integration" or "repo-end-to-end" based on breadth.',
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {
|
|
291
|
+
root: { type: 'string' },
|
|
292
|
+
title: { type: 'string' },
|
|
293
|
+
notes: { type: 'array', items: { type: 'string' } },
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'operator_ralph_reassess',
|
|
299
|
+
description: 'D5 — Reassess the current Ralph blocker against repo truth. Returns classification: still-blocked-same-reason | still-blocked-different-reason | no-longer-blocked-but-unverified | ready-for-verifying. Emits ReconcileEvent. NEVER auto-advances phase.',
|
|
300
|
+
inputSchema: {
|
|
301
|
+
type: 'object',
|
|
302
|
+
properties: {
|
|
303
|
+
root: { type: 'string' },
|
|
304
|
+
modeType: { type: 'string', enum: ['ralph'], description: 'Optional ralph mode type hint.' },
|
|
305
|
+
modeId: { type: 'string', description: 'Optional ralph id; if omitted reads current session.' },
|
|
306
|
+
currentCommitHash: { type: 'string', description: 'HEAD commit hash. If omitted, resolved from git.' },
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'operator_operator_snapshot',
|
|
312
|
+
description: 'Composite read: returns a single authoritative snapshot of all operator-relevant Operator state — session, autopilot, ultrawork, ralph, activeSkill, inbox summary, active tasks, team, recent reviews, goalScope, and unresolvedContractGaps placeholder. Recomputed fresh on every call. recentOpen is capped at 5 items and recentReviews at 10 items. Optional fields[] filter returns only specified top-level keys and rejects typos. view="converged" (default) filters superseded reviews; view="raw" shows every artifact on disk.',
|
|
313
|
+
inputSchema: {
|
|
314
|
+
type: 'object',
|
|
315
|
+
properties: {
|
|
316
|
+
root: { type: 'string' },
|
|
317
|
+
fields: {
|
|
318
|
+
type: 'array',
|
|
319
|
+
items: { type: 'string' },
|
|
320
|
+
description: 'If provided, only these top-level keys are included in the response.',
|
|
321
|
+
},
|
|
322
|
+
view: { type: 'string', enum: ['raw', 'converged'], description: 'raw=all artifacts on disk; converged=superseded items filtered out (default).' },
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: 'operator_goal_resume_or_start',
|
|
328
|
+
description: 'READ-ONLY decision tool: inspect current Operator session state and return whether to resume an active session (goal matches), start a new one, or retarget an existing one. Returns a decision, reason, matchedSession (if resuming), recommendedAction (tool + params to call next), and a full operator snapshot. Does not mutate state.',
|
|
329
|
+
inputSchema: {
|
|
330
|
+
type: 'object',
|
|
331
|
+
properties: {
|
|
332
|
+
root: { type: 'string' },
|
|
333
|
+
goal: { type: 'string', description: 'The intended goal for the session.' },
|
|
334
|
+
mode: {
|
|
335
|
+
type: 'string',
|
|
336
|
+
enum: ['ralph', 'ultrawork'],
|
|
337
|
+
description: 'Preferred mode hint. If absent, defaults to ultrawork.',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
required: ['goal'],
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
];
|
|
344
|
+
export async function handleWorkflowTool(name, context) {
|
|
345
|
+
const { root, args, invokeTool } = context;
|
|
346
|
+
switch (name) {
|
|
347
|
+
case 'operator_ralph_reassess': {
|
|
348
|
+
const ralph = getRalph(root);
|
|
349
|
+
if (!ralph) {
|
|
350
|
+
throw new Error('No Ralph state found. Start Ralph first.');
|
|
351
|
+
}
|
|
352
|
+
if (ralph.phase !== 'blocked') {
|
|
353
|
+
throw new Error(`operator_ralph_reassess: Ralph is in phase "${ralph.phase}" but reassessment only applies to blocked phase.`);
|
|
354
|
+
}
|
|
355
|
+
const providedHash = typeof args.currentCommitHash === 'string' ? args.currentCommitHash : null;
|
|
356
|
+
const currentHash = providedHash ?? createEvidenceHorizon(root).commitHash;
|
|
357
|
+
const blockedAtHash = ralph.evidenceHorizon?.commitHash ?? null;
|
|
358
|
+
const hasCommitAdvanced = blockedAtHash !== null && currentHash !== blockedAtHash && currentHash !== 'unknown';
|
|
359
|
+
const blockedAt = ralph.evidenceHorizon?.verificationRunTimestamp ?? ralph.updatedAt;
|
|
360
|
+
const recentEntries = listLedger(root, 200).filter((entry) => entry.kind === 'session' && (entry.action === 'ralph_gate_passed' || entry.action === 'ralph_gate_failed') && entry.createdAt > blockedAt);
|
|
361
|
+
const hasRecentVerification = recentEntries.length > 0;
|
|
362
|
+
const recentPassedGates = recentEntries
|
|
363
|
+
.filter((entry) => entry.action === 'ralph_gate_passed')
|
|
364
|
+
.map((entry) => typeof entry.metadata.gateId === 'string' ? entry.metadata.gateId : '');
|
|
365
|
+
const pendingOrFailedGates = ralph.verificationGates.filter((gate) => gate.status !== 'passed');
|
|
366
|
+
const allBlockerGatesNowPassed = pendingOrFailedGates.length > 0 && pendingOrFailedGates.every((gate) => recentPassedGates.includes(gate.id));
|
|
367
|
+
let classification;
|
|
368
|
+
let suggestedBlockerReason;
|
|
369
|
+
if (allBlockerGatesNowPassed) {
|
|
370
|
+
classification = 'ready-for-verifying';
|
|
371
|
+
}
|
|
372
|
+
else if (hasCommitAdvanced && hasRecentVerification) {
|
|
373
|
+
classification = 'still-blocked-different-reason';
|
|
374
|
+
suggestedBlockerReason = `Commit advanced from ${blockedAtHash ?? 'unknown'} to ${currentHash}; some gates still pending.`;
|
|
375
|
+
}
|
|
376
|
+
else if (hasCommitAdvanced && !hasRecentVerification) {
|
|
377
|
+
classification = 'no-longer-blocked-but-unverified';
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
classification = 'still-blocked-same-reason';
|
|
381
|
+
}
|
|
382
|
+
const evidenceHorizon = createEvidenceHorizon(root);
|
|
383
|
+
const reconcileEvent = {
|
|
384
|
+
kind: 'reconcile',
|
|
385
|
+
action: 'reconcile_complete',
|
|
386
|
+
schemaVersion: 1,
|
|
387
|
+
correlationId: `reconcile_${randomUUID().slice(0, 12)}`,
|
|
388
|
+
modeType: 'ralph',
|
|
389
|
+
modeId: ralph.id,
|
|
390
|
+
evidenceHorizon,
|
|
391
|
+
staleEntities: [],
|
|
392
|
+
autoApplied: [],
|
|
393
|
+
requiresOperatorDecision: [{
|
|
394
|
+
entityType: 'task',
|
|
395
|
+
entityId: ralph.id,
|
|
396
|
+
description: `Ralph reassess: ${classification}`,
|
|
397
|
+
}],
|
|
398
|
+
};
|
|
399
|
+
appendLedger(root, {
|
|
400
|
+
kind: 'reconcile',
|
|
401
|
+
action: reconcileEvent.action,
|
|
402
|
+
detail: `Ralph reassess "${ralph.id}": ${classification}`,
|
|
403
|
+
metadata: reconcileEvent,
|
|
404
|
+
});
|
|
405
|
+
return handled({
|
|
406
|
+
modeType: 'ralph',
|
|
407
|
+
modeId: ralph.id,
|
|
408
|
+
classification,
|
|
409
|
+
currentPhase: ralph.phase,
|
|
410
|
+
blockerReason: ralph.blockerReason,
|
|
411
|
+
blockerCategory: ralph.blockerCategory,
|
|
412
|
+
suggestedBlockerReason,
|
|
413
|
+
suggestedAction: classification === 'ready-for-verifying'
|
|
414
|
+
? 'Call operator_ralph_advance with toPhase=verifying'
|
|
415
|
+
: classification === 'no-longer-blocked-but-unverified'
|
|
416
|
+
? 'Run verification gates then call operator_ralph_reassess again'
|
|
417
|
+
: classification === 'still-blocked-different-reason'
|
|
418
|
+
? 'Update blockerReason via operator_ralph_block with the new category'
|
|
419
|
+
: 'Continue resolving the existing blocker',
|
|
420
|
+
evidenceHorizon,
|
|
421
|
+
hasCommitAdvanced,
|
|
422
|
+
currentCommitHash: currentHash,
|
|
423
|
+
blockedAtCommitHash: blockedAtHash,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
case 'operator_workflow_reconcile': {
|
|
427
|
+
const apply = args.apply === true;
|
|
428
|
+
const rawAgeMs = Number(args.staleReviewAgeMs);
|
|
429
|
+
const staleReviewAgeMs = Number.isFinite(rawAgeMs) && rawAgeMs >= 0 ? rawAgeMs : DEFAULT_REVIEW_STALE_MS;
|
|
430
|
+
const authority = readOperatorAuthority(root);
|
|
431
|
+
let phaseStale = false;
|
|
432
|
+
const ultraworkForReconcile = authority.ultrawork;
|
|
433
|
+
if (ultraworkForReconcile && ultraworkForReconcile.active) {
|
|
434
|
+
const reconcileContext = buildUltraworkPhaseContext(ultraworkForReconcile, authority.reviews, root);
|
|
435
|
+
const reconcileInference = inferUltraworkPhase(reconcileContext);
|
|
436
|
+
phaseStale = reconcileInference.inferredPhase !== null
|
|
437
|
+
&& reconcileInference.inferredPhase !== ultraworkForReconcile.phase
|
|
438
|
+
&& !reconcileInference.blockedByTransitionGuard;
|
|
439
|
+
}
|
|
440
|
+
const ledgerEntries = listLedger(root, 500);
|
|
441
|
+
const verificationRuns = ledgerEntries
|
|
442
|
+
.filter((entry) => entry.kind === 'review' && entry.metadata?.runId != null)
|
|
443
|
+
.map((entry) => ({
|
|
444
|
+
runId: String(entry.metadata?.runId ?? entry.action),
|
|
445
|
+
runTimestamp: entry.createdAt,
|
|
446
|
+
commitHash: String(entry.metadata?.commitHash ?? ''),
|
|
447
|
+
gateResults: [
|
|
448
|
+
...((Array.isArray(entry.metadata?.passedGates) ? entry.metadata.passedGates : []).map((gateId) => ({ gateId, passed: true }))),
|
|
449
|
+
...((Array.isArray(entry.metadata?.failedGates) ? entry.metadata.failedGates : []).map((gateId) => ({ gateId, passed: false }))),
|
|
450
|
+
],
|
|
451
|
+
}))
|
|
452
|
+
.filter((run) => run.commitHash !== '' && run.runId !== '')
|
|
453
|
+
.slice(-100);
|
|
454
|
+
const reconcileResult = reconcileWorkflowState(root, authority.tasks, authority.reviews, {
|
|
455
|
+
apply,
|
|
456
|
+
staleReviewAgeMs,
|
|
457
|
+
verificationRuns: verificationRuns.length > 0 ? verificationRuns : undefined,
|
|
458
|
+
});
|
|
459
|
+
return handled({ ...reconcileResult, phaseStale });
|
|
460
|
+
}
|
|
461
|
+
case 'operator_resume_from_repo_truth': {
|
|
462
|
+
const authority = readOperatorAuthority(root);
|
|
463
|
+
const modeId = typeof args.modeId === 'string'
|
|
464
|
+
? args.modeId
|
|
465
|
+
: authority.autopilot?.id ?? authority.ralph?.id ?? authority.ultrawork?.id;
|
|
466
|
+
const reconciled = reconcileWorkflowState(root, authority.tasks, authority.reviews, {
|
|
467
|
+
apply: true,
|
|
468
|
+
modeType: args.modeType,
|
|
469
|
+
modeId,
|
|
470
|
+
});
|
|
471
|
+
let recomputed = null;
|
|
472
|
+
const hasD4 = ultraworkToolDefinitions.some((tool) => tool.name === 'operator_ultrawork_recompute_phase');
|
|
473
|
+
if (hasD4 && authority.ultrawork?.active && invokeTool) {
|
|
474
|
+
try {
|
|
475
|
+
recomputed = await invokeTool('operator_ultrawork_recompute_phase', { root, apply: true });
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
recomputed = { skipped: true, reason: 'D4 not available or failed' };
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
recomputed = {
|
|
483
|
+
skipped: true,
|
|
484
|
+
reason: authority.ultrawork?.active
|
|
485
|
+
? hasD4
|
|
486
|
+
? 'invokeTool unavailable'
|
|
487
|
+
: 'D4 not yet landed'
|
|
488
|
+
: 'no active ultrawork',
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
let reassessed = null;
|
|
492
|
+
const hasD5 = workflowToolDefinitions.some((tool) => tool.name === 'operator_ralph_reassess');
|
|
493
|
+
if (hasD5 && authority.ralph?.active && invokeTool) {
|
|
494
|
+
try {
|
|
495
|
+
reassessed = await invokeTool('operator_ralph_reassess', { root });
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
reassessed = { skipped: true, reason: 'D5 not available or failed' };
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
reassessed = {
|
|
503
|
+
skipped: true,
|
|
504
|
+
reason: authority.ralph?.active
|
|
505
|
+
? hasD5
|
|
506
|
+
? 'invokeTool unavailable'
|
|
507
|
+
: 'D5 not yet landed'
|
|
508
|
+
: 'no active ralph',
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
const suggestedNextActions = [];
|
|
512
|
+
if (reconciled.summary.reviewInvalidations > 0) {
|
|
513
|
+
suggestedNextActions.push('operator_review_refresh — one or more reviews have updated staleState');
|
|
514
|
+
}
|
|
515
|
+
if (authority.ultrawork?.active && !hasD4) {
|
|
516
|
+
suggestedNextActions.push('operator_ultrawork_recompute_phase — land D4 to enable phase recompute');
|
|
517
|
+
}
|
|
518
|
+
if (authority.ralph?.active && !hasD5) {
|
|
519
|
+
suggestedNextActions.push('operator_ralph_reassess — land D5 to enable block-reason reassessment');
|
|
520
|
+
}
|
|
521
|
+
return handled({ reconciled, recomputed, reassessed, suggestedNextActions });
|
|
522
|
+
}
|
|
523
|
+
case 'operator_review_refresh': {
|
|
524
|
+
const reviewId = requiredString(args.reviewId, 'operator_review_refresh: reviewId is required.');
|
|
525
|
+
const allReviews = listReviews(root);
|
|
526
|
+
const review = allReviews.find((candidate) => candidate.id === reviewId);
|
|
527
|
+
if (!review) {
|
|
528
|
+
throw new Error(`Review "${reviewId}" not found.`);
|
|
529
|
+
}
|
|
530
|
+
const verificationRuns = listLedger(root, Number.MAX_SAFE_INTEGER)
|
|
531
|
+
.filter((entry) => entry.kind === 'review' && typeof entry.metadata.runId === 'string')
|
|
532
|
+
.map((entry) => {
|
|
533
|
+
const metadata = entry.metadata;
|
|
534
|
+
return {
|
|
535
|
+
runId: String(metadata.runId),
|
|
536
|
+
runTimestamp: String(metadata.runTimestamp ?? entry.createdAt),
|
|
537
|
+
commitHash: String(metadata.commitHash ?? ''),
|
|
538
|
+
gateResults: Array.isArray(metadata.gateResults)
|
|
539
|
+
? metadata.gateResults
|
|
540
|
+
: [],
|
|
541
|
+
};
|
|
542
|
+
});
|
|
543
|
+
const beforeStaleState = review.staleState;
|
|
544
|
+
const { staleState: newStaleState, trigger } = computeReviewStaleState(review, verificationRuns);
|
|
545
|
+
const supersededBy = newStaleState === 'superseded'
|
|
546
|
+
? verificationRuns
|
|
547
|
+
.filter((run) => run.runTimestamp > (review.evidenceHorizon?.verificationRunTimestamp ?? ''))
|
|
548
|
+
.sort((a, b) => b.runTimestamp.localeCompare(a.runTimestamp))[0]?.runId
|
|
549
|
+
: undefined;
|
|
550
|
+
const changed = newStaleState !== beforeStaleState;
|
|
551
|
+
if (changed) {
|
|
552
|
+
updateReview(root, reviewId, { staleState: newStaleState, supersededBy });
|
|
553
|
+
}
|
|
554
|
+
return handled({
|
|
555
|
+
before: { staleState: beforeStaleState },
|
|
556
|
+
after: { staleState: newStaleState, supersededBy },
|
|
557
|
+
changed,
|
|
558
|
+
trigger,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
case 'operator_task_reconcile': {
|
|
562
|
+
const taskId = requiredString(args.taskId, 'operator_task_reconcile: taskId is required.');
|
|
563
|
+
const task = getTask(root, taskId);
|
|
564
|
+
if (!task) {
|
|
565
|
+
throw new Error(`Task "${taskId}" not found.`);
|
|
566
|
+
}
|
|
567
|
+
const allReviews = listReviews(root);
|
|
568
|
+
const taskReviews = allReviews.filter((review) => review.taskId === task.externalId || review.taskId === task.id);
|
|
569
|
+
const reviewStale = taskReviews.some((review) => review.status === 'pending' && (review.staleState === 'stale' || review.staleState === 'superseded'));
|
|
570
|
+
const blockerStale = task.status === 'blocked' && task.blockers.length === 0;
|
|
571
|
+
const latestReconcile = listLedger(root, 50)
|
|
572
|
+
.filter((entry) => entry.kind === 'reconcile')
|
|
573
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0];
|
|
574
|
+
const evidenceOutdated = latestReconcile !== undefined && taskReviews.some((review) => {
|
|
575
|
+
const horizon = review.evidenceHorizon?.verificationRunTimestamp;
|
|
576
|
+
return horizon !== undefined && horizon < latestReconcile.createdAt;
|
|
577
|
+
});
|
|
578
|
+
const before = {
|
|
579
|
+
reviewStale: task.reviewStale,
|
|
580
|
+
blockerStale: task.blockerStale,
|
|
581
|
+
evidenceOutdated: task.evidenceOutdated,
|
|
582
|
+
};
|
|
583
|
+
const after = { reviewStale, blockerStale, evidenceOutdated };
|
|
584
|
+
const delta = {};
|
|
585
|
+
if (before.reviewStale !== after.reviewStale)
|
|
586
|
+
delta.reviewStale = after.reviewStale;
|
|
587
|
+
if (before.blockerStale !== after.blockerStale)
|
|
588
|
+
delta.blockerStale = after.blockerStale;
|
|
589
|
+
if (before.evidenceOutdated !== after.evidenceOutdated)
|
|
590
|
+
delta.evidenceOutdated = after.evidenceOutdated;
|
|
591
|
+
if (Object.keys(delta).length > 0) {
|
|
592
|
+
updateTask(root, task.id, delta);
|
|
593
|
+
}
|
|
594
|
+
return handled({ taskId, before, after, delta, changed: Object.keys(delta).length > 0 });
|
|
595
|
+
}
|
|
596
|
+
case 'operator_runtime_bootstrap_status':
|
|
597
|
+
return handled(bootstrapStatus(root));
|
|
598
|
+
case 'operator_runtime_bootstrap_repair': {
|
|
599
|
+
const before = snapshotPaths(root);
|
|
600
|
+
ensureLayout(root);
|
|
601
|
+
const after = snapshotPaths(root);
|
|
602
|
+
return handled({ ...bootstrapStatus(root), created: after.filter((path) => !before.includes(path)) });
|
|
603
|
+
}
|
|
604
|
+
case 'operator_contract_parity_run':
|
|
605
|
+
return handled(runContractParity(root, typeof args.taskId === 'string' ? args.taskId : ''));
|
|
606
|
+
case 'operator_task_create_closure_pass': {
|
|
607
|
+
const ultrawork = getUltrawork(root);
|
|
608
|
+
if (!ultrawork) {
|
|
609
|
+
throw new Error('No active Ultrawork session. Start an Ultrawork session first.');
|
|
610
|
+
}
|
|
611
|
+
if (!ultrawork.active) {
|
|
612
|
+
throw new Error(`Ultrawork session "${ultrawork.id}" is not active (phase="${ultrawork.phase}"). Cannot create closure pass.`);
|
|
613
|
+
}
|
|
614
|
+
const linkedTaskCount = ultrawork.childTasks.length + (ultrawork.taskId ? 1 : 0);
|
|
615
|
+
let closureScope;
|
|
616
|
+
if (linkedTaskCount >= 3) {
|
|
617
|
+
closureScope = 'repo-end-to-end';
|
|
618
|
+
}
|
|
619
|
+
else if (linkedTaskCount >= 1) {
|
|
620
|
+
closureScope = defaultClosureScope();
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
closureScope = 'integration';
|
|
624
|
+
}
|
|
625
|
+
const title = typeof args.title === 'string' && args.title.trim()
|
|
626
|
+
? args.title
|
|
627
|
+
: `Closure pass [${closureScope}] for ultrawork ${ultrawork.id}`;
|
|
628
|
+
const notes = Array.isArray(args.notes)
|
|
629
|
+
? args.notes
|
|
630
|
+
: [`Auto-created for ultrawork ${ultrawork.id} (${linkedTaskCount} linked tasks)`];
|
|
631
|
+
const closureTask = createTask(root, {
|
|
632
|
+
title,
|
|
633
|
+
kind: 'closure-pass',
|
|
634
|
+
phase: 'integration',
|
|
635
|
+
priority: 'high',
|
|
636
|
+
notes,
|
|
637
|
+
metadata: {
|
|
638
|
+
modeType: 'ultrawork',
|
|
639
|
+
modeId: ultrawork.id,
|
|
640
|
+
closureScope,
|
|
641
|
+
linkedTaskCount,
|
|
642
|
+
},
|
|
643
|
+
});
|
|
644
|
+
updateTask(root, closureTask.id, { closureScope });
|
|
645
|
+
linkTaskRef(root, closureTask.id);
|
|
646
|
+
return handled({
|
|
647
|
+
task: { ...closureTask, closureScope },
|
|
648
|
+
closureScope,
|
|
649
|
+
modeType: 'ultrawork',
|
|
650
|
+
modeId: ultrawork.id,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
case 'operator_operator_snapshot': {
|
|
654
|
+
const authority = readOperatorAuthority(root);
|
|
655
|
+
const snapshotView = args.view === 'raw' ? 'raw' : 'converged';
|
|
656
|
+
const snapshot = composeOperatorSnapshot(authority, snapshotView);
|
|
657
|
+
const fields = Array.isArray(args.fields) ? args.fields : null;
|
|
658
|
+
if (fields && fields.length > 0) {
|
|
659
|
+
const validFields = asSnapshotFieldSet();
|
|
660
|
+
const invalid = fields.filter((field) => !validFields.has(field));
|
|
661
|
+
if (invalid.length > 0) {
|
|
662
|
+
throw new Error(`Unknown operator snapshot field(s): ${invalid.join(', ')}. Allowed fields: ${SNAPSHOT_FIELDS.join(', ')}.`);
|
|
663
|
+
}
|
|
664
|
+
const filtered = {};
|
|
665
|
+
for (const field of fields) {
|
|
666
|
+
if (Object.prototype.hasOwnProperty.call(snapshot, field)) {
|
|
667
|
+
filtered[field] = snapshot[field];
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return handled(filtered);
|
|
671
|
+
}
|
|
672
|
+
return handled(snapshot);
|
|
673
|
+
}
|
|
674
|
+
case 'operator_goal_resume_or_start': {
|
|
675
|
+
const goal = requiredString(normalizeOperatorGoal(String(args.goal ?? '')).trim(), 'operator_goal_resume_or_start: goal is required.');
|
|
676
|
+
const modeHint = typeof args.mode === 'string' && (args.mode === 'ralph' || args.mode === 'ultrawork')
|
|
677
|
+
? args.mode
|
|
678
|
+
: 'ultrawork';
|
|
679
|
+
const authority = readOperatorAuthority(root);
|
|
680
|
+
const { ralph, ultrawork } = authority;
|
|
681
|
+
const snapshot = composeOperatorSnapshot(authority);
|
|
682
|
+
const activeUltrawork = ultrawork?.active ? ultrawork : null;
|
|
683
|
+
const activeRalph = ralph?.active ? ralph : null;
|
|
684
|
+
let decision;
|
|
685
|
+
let reason;
|
|
686
|
+
let matchedSession = null;
|
|
687
|
+
let recommendedAction = null;
|
|
688
|
+
const activeForMode = modeHint === 'ralph' ? activeRalph : activeUltrawork;
|
|
689
|
+
const currentGoal = activeGoalForMode(modeHint, activeRalph, activeUltrawork);
|
|
690
|
+
if (!activeForMode) {
|
|
691
|
+
decision = 'start';
|
|
692
|
+
reason = `No active ${modeHint} session found. Start one with goal "${goal}".`;
|
|
693
|
+
recommendedAction = {
|
|
694
|
+
tool: modeHint === 'ralph' ? 'operator_ralph_start' : 'operator_ultrawork_start',
|
|
695
|
+
params: modeHint === 'ralph' ? { goal } : { intent: goal },
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
else if (currentGoal !== null && currentGoal.trim() === goal) {
|
|
699
|
+
decision = 'resume';
|
|
700
|
+
reason = `Active ${modeHint} session already has goal "${goal}". Nothing to do.`;
|
|
701
|
+
matchedSession = {
|
|
702
|
+
mode: modeHint,
|
|
703
|
+
currentGoal,
|
|
704
|
+
goalScope: activeForMode.goalScope ?? null,
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
decision = 'retarget-needed';
|
|
709
|
+
reason = `Active ${modeHint} has goal "${currentGoal ?? ''}"; explicit retarget required.`;
|
|
710
|
+
recommendedAction = {
|
|
711
|
+
tool: modeHint === 'ralph' ? 'operator_ralph_retarget' : 'operator_ultrawork_retarget',
|
|
712
|
+
params: modeHint === 'ralph'
|
|
713
|
+
? { goal, mode: 'replace-intent' }
|
|
714
|
+
: { intent: goal, mode: 'replace-intent' },
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
return handled({ decision, reason, matchedSession, recommendedAction, snapshot });
|
|
718
|
+
}
|
|
719
|
+
default:
|
|
720
|
+
return UNHANDLED;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
//# sourceMappingURL=workflow.js.map
|