pi-subagents 0.69.0 → 0.70.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/CHANGELOG.md +41 -0
- package/agents/reviewer.md +3 -2
- package/docs/agents.md +6 -2
- package/docs/configuration.md +1 -1
- package/docs/extension-api.md +1 -1
- package/docs/models.md +3 -1
- package/docs/observability.md +6 -0
- package/docs/watchdog.md +2 -0
- package/docs/workflows.md +6 -2
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -0
- package/index.js +10 -0
- package/index.js.map +1 -0
- package/package.json +89 -73
- package/runner-peer-loader.mjs +4 -7
- package/runner-peer-preload.mjs +5 -7
- package/skills/pi-subagents/references/prompting-and-roles.md +2 -2
- package/src/agents/advertised-agent-prompt.d.ts +8 -0
- package/src/agents/advertised-agent-prompt.d.ts.map +1 -0
- package/src/agents/advertised-agent-prompt.js +77 -0
- package/src/agents/advertised-agent-prompt.js.map +1 -0
- package/src/agents/agent-management.d.ts +27 -0
- package/src/agents/agent-management.d.ts.map +1 -0
- package/src/agents/agent-management.js +1528 -0
- package/src/agents/agent-management.js.map +1 -0
- package/src/agents/agent-memory.d.ts +49 -0
- package/src/agents/agent-memory.d.ts.map +1 -0
- package/src/agents/agent-memory.js +349 -0
- package/src/agents/agent-memory.js.map +1 -0
- package/src/agents/agent-refinements.d.ts +100 -0
- package/src/agents/agent-refinements.d.ts.map +1 -0
- package/src/agents/agent-refinements.js +569 -0
- package/src/agents/agent-refinements.js.map +1 -0
- package/src/agents/agent-scope.d.ts +3 -0
- package/src/agents/agent-scope.d.ts.map +1 -0
- package/src/agents/agent-scope.js +6 -0
- package/src/agents/agent-scope.js.map +1 -0
- package/src/agents/agent-selection.d.ts +3 -0
- package/src/agents/agent-selection.d.ts.map +1 -0
- package/src/agents/agent-selection.js +23 -0
- package/src/agents/agent-selection.js.map +1 -0
- package/src/agents/agent-serializer.d.ts +8 -0
- package/src/agents/agent-serializer.d.ts.map +1 -0
- package/src/agents/agent-serializer.js +200 -0
- package/src/agents/agent-serializer.js.map +1 -0
- package/src/agents/agents.d.ts +313 -0
- package/src/agents/agents.d.ts.map +1 -0
- package/src/agents/agents.js +2622 -0
- package/src/agents/agents.js.map +1 -0
- package/src/agents/builtin-names.d.ts +2 -0
- package/src/agents/builtin-names.d.ts.map +1 -0
- package/src/agents/builtin-names.js +17 -0
- package/src/agents/builtin-names.js.map +1 -0
- package/src/agents/chain-serializer.d.ts +7 -0
- package/src/agents/chain-serializer.d.ts.map +1 -0
- package/src/agents/chain-serializer.js +319 -0
- package/src/agents/chain-serializer.js.map +1 -0
- package/src/agents/frontmatter.d.ts +16 -0
- package/src/agents/frontmatter.d.ts.map +1 -0
- package/src/agents/frontmatter.js +142 -0
- package/src/agents/frontmatter.js.map +1 -0
- package/src/agents/identity.d.ts +8 -0
- package/src/agents/identity.d.ts.map +1 -0
- package/src/agents/identity.js +30 -0
- package/src/agents/identity.js.map +1 -0
- package/src/agents/proactive-skills.d.ts +35 -0
- package/src/agents/proactive-skills.d.ts.map +1 -0
- package/src/agents/proactive-skills.js +154 -0
- package/src/agents/proactive-skills.js.map +1 -0
- package/src/agents/runtime-agent-events.d.ts +27 -0
- package/src/agents/runtime-agent-events.d.ts.map +1 -0
- package/src/agents/runtime-agent-events.js +53 -0
- package/src/agents/runtime-agent-events.js.map +1 -0
- package/src/agents/runtime-agent-registry.d.ts +59 -0
- package/src/agents/runtime-agent-registry.d.ts.map +1 -0
- package/src/agents/runtime-agent-registry.js +390 -0
- package/src/agents/runtime-agent-registry.js.map +1 -0
- package/src/agents/skills.d.ts +33 -0
- package/src/agents/skills.d.ts.map +1 -0
- package/src/agents/skills.js +685 -0
- package/src/agents/skills.js.map +1 -0
- package/src/api/agents.d.ts +5 -0
- package/src/api/agents.d.ts.map +1 -0
- package/src/api/agents.js +3 -0
- package/src/api/agents.js.map +1 -0
- package/src/api/background-work.d.ts +39 -0
- package/src/api/background-work.d.ts.map +1 -0
- package/src/api/background-work.js +165 -0
- package/src/api/background-work.js.map +1 -0
- package/src/api/capability-ceiling.d.ts +2 -0
- package/src/api/capability-ceiling.d.ts.map +1 -0
- package/src/api/capability-ceiling.js +2 -0
- package/src/api/capability-ceiling.js.map +1 -0
- package/src/api/child-tool-plan.d.ts +2 -0
- package/src/api/child-tool-plan.d.ts.map +1 -0
- package/src/api/child-tool-plan.js +2 -0
- package/src/api/child-tool-plan.js.map +1 -0
- package/src/api/control-channel.d.ts +2 -0
- package/src/api/control-channel.d.ts.map +1 -0
- package/src/api/control-channel.js +2 -0
- package/src/api/control-channel.js.map +1 -0
- package/src/api/delegation.d.ts +99 -0
- package/src/api/delegation.d.ts.map +1 -0
- package/src/api/delegation.js +9 -0
- package/src/api/delegation.js.map +1 -0
- package/src/api/external-job-provider.d.ts +58 -0
- package/src/api/external-job-provider.d.ts.map +1 -0
- package/src/api/external-job-provider.js +140 -0
- package/src/api/external-job-provider.js.map +1 -0
- package/src/api/external-runs.d.ts +48 -0
- package/src/api/external-runs.d.ts.map +1 -0
- package/src/api/external-runs.js +245 -0
- package/src/api/external-runs.js.map +1 -0
- package/src/api/intercom-bridge.d.ts +2 -0
- package/src/api/intercom-bridge.d.ts.map +1 -0
- package/src/api/intercom-bridge.js +2 -0
- package/src/api/intercom-bridge.js.map +1 -0
- package/src/api/preflight.d.ts +173 -0
- package/src/api/preflight.d.ts.map +1 -0
- package/src/api/preflight.js +362 -0
- package/src/api/preflight.js.map +1 -0
- package/src/api/project-panes.d.ts +8 -0
- package/src/api/project-panes.d.ts.map +1 -0
- package/src/api/project-panes.js +8 -0
- package/src/api/project-panes.js.map +1 -0
- package/src/api/required-child-extensions.d.ts +2 -0
- package/src/api/required-child-extensions.d.ts.map +1 -0
- package/src/api/required-child-extensions.js +2 -0
- package/src/api/required-child-extensions.js.map +1 -0
- package/src/api/shared-types.d.ts +2 -0
- package/src/api/shared-types.d.ts.map +1 -0
- package/src/api/shared-types.js +2 -0
- package/src/api/shared-types.js.map +1 -0
- package/src/api/workflow-resources.d.ts +3 -0
- package/src/api/workflow-resources.d.ts.map +1 -0
- package/src/api/workflow-resources.js +2 -0
- package/src/api/workflow-resources.js.map +1 -0
- package/src/extension/config.d.ts +8 -0
- package/src/extension/config.d.ts.map +1 -0
- package/src/extension/config.js +245 -0
- package/src/extension/config.js.map +1 -0
- package/src/extension/control-notices.d.ts +19 -0
- package/src/extension/control-notices.d.ts.map +1 -0
- package/src/extension/control-notices.js +34 -0
- package/src/extension/control-notices.js.map +1 -0
- package/src/extension/doctor.d.ts +33 -0
- package/src/extension/doctor.d.ts.map +1 -0
- package/src/extension/doctor.js +231 -0
- package/src/extension/doctor.js.map +1 -0
- package/src/extension/fanout-child.d.ts +7 -0
- package/src/extension/fanout-child.d.ts.map +1 -0
- package/src/extension/fanout-child.js +261 -0
- package/src/extension/fanout-child.js.map +1 -0
- package/src/extension/herdr-pi-bridge.d.ts +17 -0
- package/src/extension/herdr-pi-bridge.d.ts.map +1 -0
- package/src/extension/herdr-pi-bridge.js +243 -0
- package/src/extension/herdr-pi-bridge.js.map +1 -0
- package/src/extension/index.d.ts +20 -0
- package/src/extension/index.d.ts.map +1 -0
- package/src/extension/index.js +1108 -0
- package/src/extension/index.js.map +1 -0
- package/src/extension/public-execution.d.ts +62 -0
- package/src/extension/public-execution.d.ts.map +1 -0
- package/src/extension/public-execution.js +174 -0
- package/src/extension/public-execution.js.map +1 -0
- package/src/extension/rpc.d.ts +83 -0
- package/src/extension/rpc.d.ts.map +1 -0
- package/src/extension/rpc.js +687 -0
- package/src/extension/rpc.js.map +1 -0
- package/src/extension/schemas.d.ts +252 -0
- package/src/extension/schemas.d.ts.map +1 -0
- package/src/extension/schemas.js +396 -0
- package/src/extension/schemas.js.map +1 -0
- package/src/extension/steering-notices.d.ts +15 -0
- package/src/extension/steering-notices.d.ts.map +1 -0
- package/src/extension/steering-notices.js +23 -0
- package/src/extension/steering-notices.js.map +1 -0
- package/src/extension/subagent-guide.d.ts +4 -0
- package/src/extension/subagent-guide.d.ts.map +1 -0
- package/src/extension/subagent-guide.js +35 -0
- package/src/extension/subagent-guide.js.map +1 -0
- package/src/extension/tool-description.d.ts +20 -0
- package/src/extension/tool-description.d.ts.map +1 -0
- package/src/extension/tool-description.js +160 -0
- package/src/extension/tool-description.js.map +1 -0
- package/src/extension/tool-result.d.ts +10 -0
- package/src/extension/tool-result.d.ts.map +1 -0
- package/src/extension/tool-result.js +17 -0
- package/src/extension/tool-result.js.map +1 -0
- package/src/inspectors/actions.d.ts +23 -0
- package/src/inspectors/actions.d.ts.map +1 -0
- package/src/inspectors/actions.js +155 -0
- package/src/inspectors/actions.js.map +1 -0
- package/src/inspectors/ghostty/actions.d.ts +12 -0
- package/src/inspectors/ghostty/actions.d.ts.map +1 -0
- package/src/inspectors/ghostty/actions.js +63 -0
- package/src/inspectors/ghostty/actions.js.map +1 -0
- package/src/inspectors/ghostty/plugin.d.ts +8 -0
- package/src/inspectors/ghostty/plugin.d.ts.map +1 -0
- package/src/inspectors/ghostty/plugin.js +24 -0
- package/src/inspectors/ghostty/plugin.js.map +1 -0
- package/src/inspectors/herdr/actions.d.ts +26 -0
- package/src/inspectors/herdr/actions.d.ts.map +1 -0
- package/src/inspectors/herdr/actions.js +134 -0
- package/src/inspectors/herdr/actions.js.map +1 -0
- package/src/inspectors/herdr/client.d.ts +42 -0
- package/src/inspectors/herdr/client.d.ts.map +1 -0
- package/src/inspectors/herdr/client.js +130 -0
- package/src/inspectors/herdr/client.js.map +1 -0
- package/src/inspectors/herdr/focus.d.ts +25 -0
- package/src/inspectors/herdr/focus.d.ts.map +1 -0
- package/src/inspectors/herdr/focus.js +50 -0
- package/src/inspectors/herdr/focus.js.map +1 -0
- package/src/inspectors/herdr/plugin.d.ts +7 -0
- package/src/inspectors/herdr/plugin.d.ts.map +1 -0
- package/src/inspectors/herdr/plugin.js +15 -0
- package/src/inspectors/herdr/plugin.js.map +1 -0
- package/src/inspectors/herdr/project-panes.d.ts +137 -0
- package/src/inspectors/herdr/project-panes.d.ts.map +1 -0
- package/src/inspectors/herdr/project-panes.js +608 -0
- package/src/inspectors/herdr/project-panes.js.map +1 -0
- package/src/inspectors/inspector-runner.d.ts +24 -0
- package/src/inspectors/inspector-runner.d.ts.map +1 -0
- package/src/inspectors/inspector-runner.js +162 -0
- package/src/inspectors/inspector-runner.js.map +1 -0
- package/src/inspectors/plugins.d.ts +4 -0
- package/src/inspectors/plugins.d.ts.map +1 -0
- package/src/inspectors/plugins.js +7 -0
- package/src/inspectors/plugins.js.map +1 -0
- package/src/inspectors/session-roots-codec.d.ts +16 -0
- package/src/inspectors/session-roots-codec.d.ts.map +1 -0
- package/src/inspectors/session-roots-codec.js +33 -0
- package/src/inspectors/session-roots-codec.js.map +1 -0
- package/src/inspectors/shell-command.d.ts +2 -0
- package/src/inspectors/shell-command.d.ts.map +1 -0
- package/src/inspectors/shell-command.js +17 -0
- package/src/inspectors/shell-command.js.map +1 -0
- package/src/inspectors/types.d.ts +49 -0
- package/src/inspectors/types.d.ts.map +1 -0
- package/src/inspectors/types.js +2 -0
- package/src/inspectors/types.js.map +1 -0
- package/src/integrations/herdr-status.d.ts +46 -0
- package/src/integrations/herdr-status.d.ts.map +1 -0
- package/src/integrations/herdr-status.js +371 -0
- package/src/integrations/herdr-status.js.map +1 -0
- package/src/integrations/pi-web-session-liveness.d.ts +20 -0
- package/src/integrations/pi-web-session-liveness.d.ts.map +1 -0
- package/src/integrations/pi-web-session-liveness.js +54 -0
- package/src/integrations/pi-web-session-liveness.js.map +1 -0
- package/src/intercom/intercom-bridge.d.ts +59 -0
- package/src/intercom/intercom-bridge.d.ts.map +1 -0
- package/src/intercom/intercom-bridge.js +192 -0
- package/src/intercom/intercom-bridge.js.map +1 -0
- package/src/intercom/native-supervisor-channel.d.ts +64 -0
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -0
- package/src/intercom/native-supervisor-channel.js +894 -0
- package/src/intercom/native-supervisor-channel.js.map +1 -0
- package/src/intercom/result-intercom.d.ts +36 -0
- package/src/intercom/result-intercom.d.ts.map +1 -0
- package/src/intercom/result-intercom.js +372 -0
- package/src/intercom/result-intercom.js.map +1 -0
- package/src/intercom/supervisor-ui.d.ts +40 -0
- package/src/intercom/supervisor-ui.d.ts.map +1 -0
- package/src/intercom/supervisor-ui.js +202 -0
- package/src/intercom/supervisor-ui.js.map +1 -0
- package/src/missions/actions.d.ts +55 -0
- package/src/missions/actions.d.ts.map +1 -0
- package/src/missions/actions.js +396 -0
- package/src/missions/actions.js.map +1 -0
- package/src/missions/goal-driver.d.ts +16 -0
- package/src/missions/goal-driver.d.ts.map +1 -0
- package/src/missions/goal-driver.js +157 -0
- package/src/missions/goal-driver.js.map +1 -0
- package/src/missions/lifecycle.d.ts +40 -0
- package/src/missions/lifecycle.d.ts.map +1 -0
- package/src/missions/lifecycle.js +352 -0
- package/src/missions/lifecycle.js.map +1 -0
- package/src/missions/store.d.ts +22 -0
- package/src/missions/store.d.ts.map +1 -0
- package/src/missions/store.js +573 -0
- package/src/missions/store.js.map +1 -0
- package/src/missions/types.d.ts +168 -0
- package/src/missions/types.d.ts.map +1 -0
- package/src/missions/types.js +10 -0
- package/src/missions/types.js.map +1 -0
- package/src/missions/workflow-state.d.ts +15 -0
- package/src/missions/workflow-state.d.ts.map +1 -0
- package/src/missions/workflow-state.js +274 -0
- package/src/missions/workflow-state.js.map +1 -0
- package/src/policy/authority.d.ts +10 -0
- package/src/policy/authority.d.ts.map +1 -0
- package/src/policy/authority.js +42 -0
- package/src/policy/authority.js.map +1 -0
- package/src/profiles/profiles.d.ts +135 -0
- package/src/profiles/profiles.d.ts.map +1 -0
- package/src/profiles/profiles.js +520 -0
- package/src/profiles/profiles.js.map +1 -0
- package/src/runs/background/active-async-capacity.d.ts +100 -0
- package/src/runs/background/active-async-capacity.d.ts.map +1 -0
- package/src/runs/background/active-async-capacity.js +492 -0
- package/src/runs/background/active-async-capacity.js.map +1 -0
- package/src/runs/background/active-run-index.d.ts +13 -0
- package/src/runs/background/active-run-index.d.ts.map +1 -0
- package/src/runs/background/active-run-index.js +158 -0
- package/src/runs/background/active-run-index.js.map +1 -0
- package/src/runs/background/async-execution.d.ts +274 -0
- package/src/runs/background/async-execution.d.ts.map +1 -0
- package/src/runs/background/async-execution.js +1989 -0
- package/src/runs/background/async-execution.js.map +1 -0
- package/src/runs/background/async-job-tracker.d.ts +28 -0
- package/src/runs/background/async-job-tracker.d.ts.map +1 -0
- package/src/runs/background/async-job-tracker.js +876 -0
- package/src/runs/background/async-job-tracker.js.map +1 -0
- package/src/runs/background/async-resume.d.ts +59 -0
- package/src/runs/background/async-resume.d.ts.map +1 -0
- package/src/runs/background/async-resume.js +670 -0
- package/src/runs/background/async-resume.js.map +1 -0
- package/src/runs/background/async-retention.d.ts +45 -0
- package/src/runs/background/async-retention.d.ts.map +1 -0
- package/src/runs/background/async-retention.js +884 -0
- package/src/runs/background/async-retention.js.map +1 -0
- package/src/runs/background/async-status-snapshot.d.ts +10 -0
- package/src/runs/background/async-status-snapshot.d.ts.map +1 -0
- package/src/runs/background/async-status-snapshot.js +25 -0
- package/src/runs/background/async-status-snapshot.js.map +1 -0
- package/src/runs/background/async-status.d.ts +169 -0
- package/src/runs/background/async-status.d.ts.map +1 -0
- package/src/runs/background/async-status.js +673 -0
- package/src/runs/background/async-status.js.map +1 -0
- package/src/runs/background/auto-drain.d.ts +17 -0
- package/src/runs/background/auto-drain.d.ts.map +1 -0
- package/src/runs/background/auto-drain.js +73 -0
- package/src/runs/background/auto-drain.js.map +1 -0
- package/src/runs/background/binary-bootstrap.d.ts +9 -0
- package/src/runs/background/binary-bootstrap.d.ts.map +1 -0
- package/src/runs/background/binary-bootstrap.js +41 -0
- package/src/runs/background/binary-bootstrap.js.map +1 -0
- package/src/runs/background/chain-append.d.ts +35 -0
- package/src/runs/background/chain-append.d.ts.map +1 -0
- package/src/runs/background/chain-append.js +300 -0
- package/src/runs/background/chain-append.js.map +1 -0
- package/src/runs/background/chain-root-attachment.d.ts +49 -0
- package/src/runs/background/chain-root-attachment.d.ts.map +1 -0
- package/src/runs/background/chain-root-attachment.js +184 -0
- package/src/runs/background/chain-root-attachment.js.map +1 -0
- package/src/runs/background/completion-batcher.d.ts +52 -0
- package/src/runs/background/completion-batcher.d.ts.map +1 -0
- package/src/runs/background/completion-batcher.js +120 -0
- package/src/runs/background/completion-batcher.js.map +1 -0
- package/src/runs/background/completion-dedupe.d.ts +14 -0
- package/src/runs/background/completion-dedupe.d.ts.map +1 -0
- package/src/runs/background/completion-dedupe.js +49 -0
- package/src/runs/background/completion-dedupe.js.map +1 -0
- package/src/runs/background/completion-replay.d.ts +48 -0
- package/src/runs/background/completion-replay.d.ts.map +1 -0
- package/src/runs/background/completion-replay.js +267 -0
- package/src/runs/background/completion-replay.js.map +1 -0
- package/src/runs/background/control-channel.d.ts +156 -0
- package/src/runs/background/control-channel.d.ts.map +1 -0
- package/src/runs/background/control-channel.js +521 -0
- package/src/runs/background/control-channel.js.map +1 -0
- package/src/runs/background/fleet-view.d.ts +64 -0
- package/src/runs/background/fleet-view.d.ts.map +1 -0
- package/src/runs/background/fleet-view.js +648 -0
- package/src/runs/background/fleet-view.js.map +1 -0
- package/src/runs/background/index-segment.d.ts +16 -0
- package/src/runs/background/index-segment.d.ts.map +1 -0
- package/src/runs/background/index-segment.js +59 -0
- package/src/runs/background/index-segment.js.map +1 -0
- package/src/runs/background/inspect-rpc.d.ts +60 -0
- package/src/runs/background/inspect-rpc.d.ts.map +1 -0
- package/src/runs/background/inspect-rpc.js +406 -0
- package/src/runs/background/inspect-rpc.js.map +1 -0
- package/src/runs/background/notify.d.ts +162 -0
- package/src/runs/background/notify.d.ts.map +1 -0
- package/src/runs/background/notify.js +665 -0
- package/src/runs/background/notify.js.map +1 -0
- package/src/runs/background/owned-process-tree.d.ts +11 -0
- package/src/runs/background/owned-process-tree.d.ts.map +1 -0
- package/src/runs/background/owned-process-tree.js +117 -0
- package/src/runs/background/owned-process-tree.js.map +1 -0
- package/src/runs/background/parallel-groups.d.ts +4 -0
- package/src/runs/background/parallel-groups.d.ts.map +1 -0
- package/src/runs/background/parallel-groups.js +47 -0
- package/src/runs/background/parallel-groups.js.map +1 -0
- package/src/runs/background/process-terminal.d.ts +34 -0
- package/src/runs/background/process-terminal.d.ts.map +1 -0
- package/src/runs/background/process-terminal.js +305 -0
- package/src/runs/background/process-terminal.js.map +1 -0
- package/src/runs/background/result-delivery-ownership.d.ts +11 -0
- package/src/runs/background/result-delivery-ownership.d.ts.map +1 -0
- package/src/runs/background/result-delivery-ownership.js +37 -0
- package/src/runs/background/result-delivery-ownership.js.map +1 -0
- package/src/runs/background/result-files.d.ts +33 -0
- package/src/runs/background/result-files.d.ts.map +1 -0
- package/src/runs/background/result-files.js +528 -0
- package/src/runs/background/result-files.js.map +1 -0
- package/src/runs/background/result-watcher.d.ts +87 -0
- package/src/runs/background/result-watcher.d.ts.map +1 -0
- package/src/runs/background/result-watcher.js +764 -0
- package/src/runs/background/result-watcher.js.map +1 -0
- package/src/runs/background/resume-guidance.d.ts +5 -0
- package/src/runs/background/resume-guidance.d.ts.map +1 -0
- package/src/runs/background/resume-guidance.js +57 -0
- package/src/runs/background/resume-guidance.js.map +1 -0
- package/src/runs/background/retained-children.d.ts +25 -0
- package/src/runs/background/retained-children.d.ts.map +1 -0
- package/src/runs/background/retained-children.js +128 -0
- package/src/runs/background/retained-children.js.map +1 -0
- package/src/runs/background/retained-nested-route-tracker.d.ts +13 -0
- package/src/runs/background/retained-nested-route-tracker.d.ts.map +1 -0
- package/src/runs/background/retained-nested-route-tracker.js +91 -0
- package/src/runs/background/retained-nested-route-tracker.js.map +1 -0
- package/src/runs/background/run-child-session.d.ts +123 -0
- package/src/runs/background/run-child-session.d.ts.map +1 -0
- package/src/runs/background/run-child-session.js +602 -0
- package/src/runs/background/run-child-session.js.map +1 -0
- package/src/runs/background/run-id-query.d.ts +4 -0
- package/src/runs/background/run-id-query.d.ts.map +1 -0
- package/src/runs/background/run-id-query.js +7 -0
- package/src/runs/background/run-id-query.js.map +1 -0
- package/src/runs/background/run-id-resolver.d.ts +23 -0
- package/src/runs/background/run-id-resolver.d.ts.map +1 -0
- package/src/runs/background/run-id-resolver.js +170 -0
- package/src/runs/background/run-id-resolver.js.map +1 -0
- package/src/runs/background/run-status.d.ts +26 -0
- package/src/runs/background/run-status.d.ts.map +1 -0
- package/src/runs/background/run-status.js +826 -0
- package/src/runs/background/run-status.js.map +1 -0
- package/src/runs/background/runner-aliases.d.ts +17 -0
- package/src/runs/background/runner-aliases.d.ts.map +1 -0
- package/src/runs/background/runner-aliases.js +141 -0
- package/src/runs/background/runner-aliases.js.map +1 -0
- package/src/runs/background/runner-child-launch.d.ts +24 -0
- package/src/runs/background/runner-child-launch.d.ts.map +1 -0
- package/src/runs/background/runner-child-launch.js +68 -0
- package/src/runs/background/runner-child-launch.js.map +1 -0
- package/src/runs/background/runner-child-sessions.d.ts +7 -0
- package/src/runs/background/runner-child-sessions.d.ts.map +1 -0
- package/src/runs/background/runner-child-sessions.js +35 -0
- package/src/runs/background/runner-child-sessions.js.map +1 -0
- package/src/runs/background/runner-http-dispatcher.d.ts +43 -0
- package/src/runs/background/runner-http-dispatcher.d.ts.map +1 -0
- package/src/runs/background/runner-http-dispatcher.js +114 -0
- package/src/runs/background/runner-http-dispatcher.js.map +1 -0
- package/src/runs/background/scheduled-runs.d.ts +116 -0
- package/src/runs/background/scheduled-runs.d.ts.map +1 -0
- package/src/runs/background/scheduled-runs.js +1024 -0
- package/src/runs/background/scheduled-runs.js.map +1 -0
- package/src/runs/background/stale-run-reconciler.d.ts +37 -0
- package/src/runs/background/stale-run-reconciler.d.ts.map +1 -0
- package/src/runs/background/stale-run-reconciler.js +393 -0
- package/src/runs/background/stale-run-reconciler.js.map +1 -0
- package/src/runs/background/steering.d.ts +52 -0
- package/src/runs/background/steering.d.ts.map +1 -0
- package/src/runs/background/steering.js +247 -0
- package/src/runs/background/steering.js.map +1 -0
- package/src/runs/background/subagent-runner.d.ts +201 -0
- package/src/runs/background/subagent-runner.d.ts.map +1 -0
- package/src/runs/background/subagent-runner.js +5134 -0
- package/src/runs/background/subagent-runner.js.map +1 -0
- package/src/runs/background/subagent-wait.d.ts +122 -0
- package/src/runs/background/subagent-wait.d.ts.map +1 -0
- package/src/runs/background/subagent-wait.js +735 -0
- package/src/runs/background/subagent-wait.js.map +1 -0
- package/src/runs/background/terminal-run-index.d.ts +8 -0
- package/src/runs/background/terminal-run-index.d.ts.map +1 -0
- package/src/runs/background/terminal-run-index.js +123 -0
- package/src/runs/background/terminal-run-index.js.map +1 -0
- package/src/runs/background/top-level-async.d.ts +8 -0
- package/src/runs/background/top-level-async.d.ts.map +1 -0
- package/src/runs/background/top-level-async.js +6 -0
- package/src/runs/background/top-level-async.js.map +1 -0
- package/src/runs/background/wait-completions.d.ts +29 -0
- package/src/runs/background/wait-completions.d.ts.map +1 -0
- package/src/runs/background/wait-completions.js +264 -0
- package/src/runs/background/wait-completions.js.map +1 -0
- package/src/runs/background/wait-config.d.ts +9 -0
- package/src/runs/background/wait-config.d.ts.map +1 -0
- package/src/runs/background/wait-config.js +47 -0
- package/src/runs/background/wait-config.js.map +1 -0
- package/src/runs/background/wait-subscriptions.d.ts +27 -0
- package/src/runs/background/wait-subscriptions.d.ts.map +1 -0
- package/src/runs/background/wait-subscriptions.js +337 -0
- package/src/runs/background/wait-subscriptions.js.map +1 -0
- package/src/runs/background/wait-tool.d.ts +7 -0
- package/src/runs/background/wait-tool.d.ts.map +1 -0
- package/src/runs/background/wait-tool.js +36 -0
- package/src/runs/background/wait-tool.js.map +1 -0
- package/src/runs/foreground/async-dismiss-action.d.ts +7 -0
- package/src/runs/foreground/async-dismiss-action.d.ts.map +1 -0
- package/src/runs/foreground/async-dismiss-action.js +82 -0
- package/src/runs/foreground/async-dismiss-action.js.map +1 -0
- package/src/runs/foreground/async-steering-action.d.ts +32 -0
- package/src/runs/foreground/async-steering-action.d.ts.map +1 -0
- package/src/runs/foreground/async-steering-action.js +270 -0
- package/src/runs/foreground/async-steering-action.js.map +1 -0
- package/src/runs/foreground/async-stop-action.d.ts +7 -0
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -0
- package/src/runs/foreground/async-stop-action.js +171 -0
- package/src/runs/foreground/async-stop-action.js.map +1 -0
- package/src/runs/foreground/execution.d.ts +11 -0
- package/src/runs/foreground/execution.d.ts.map +1 -0
- package/src/runs/foreground/execution.js +2186 -0
- package/src/runs/foreground/execution.js.map +1 -0
- package/src/runs/foreground/foreground-control.d.ts +25 -0
- package/src/runs/foreground/foreground-control.d.ts.map +1 -0
- package/src/runs/foreground/foreground-control.js +139 -0
- package/src/runs/foreground/foreground-control.js.map +1 -0
- package/src/runs/foreground/foreground-history.d.ts +12 -0
- package/src/runs/foreground/foreground-history.d.ts.map +1 -0
- package/src/runs/foreground/foreground-history.js +165 -0
- package/src/runs/foreground/foreground-history.js.map +1 -0
- package/src/runs/foreground/prompt-audit.d.ts +33 -0
- package/src/runs/foreground/prompt-audit.d.ts.map +1 -0
- package/src/runs/foreground/prompt-audit.js +143 -0
- package/src/runs/foreground/prompt-audit.js.map +1 -0
- package/src/runs/foreground/subagent-executor.d.ts +296 -0
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -0
- package/src/runs/foreground/subagent-executor.js +7047 -0
- package/src/runs/foreground/subagent-executor.js.map +1 -0
- package/src/runs/foreground/workflow-detach-reconcile.d.ts +16 -0
- package/src/runs/foreground/workflow-detach-reconcile.d.ts.map +1 -0
- package/src/runs/foreground/workflow-detach-reconcile.js +284 -0
- package/src/runs/foreground/workflow-detach-reconcile.js.map +1 -0
- package/src/runs/foreground/workflow-foreground-steering.d.ts +44 -0
- package/src/runs/foreground/workflow-foreground-steering.d.ts.map +1 -0
- package/src/runs/foreground/workflow-foreground-steering.js +149 -0
- package/src/runs/foreground/workflow-foreground-steering.js.map +1 -0
- package/src/runs/shared/abort-recovery.d.ts +27 -0
- package/src/runs/shared/abort-recovery.d.ts.map +1 -0
- package/src/runs/shared/abort-recovery.js +109 -0
- package/src/runs/shared/abort-recovery.js.map +1 -0
- package/src/runs/shared/acceptance.d.ts +145 -0
- package/src/runs/shared/acceptance.d.ts.map +1 -0
- package/src/runs/shared/acceptance.js +1650 -0
- package/src/runs/shared/acceptance.js.map +1 -0
- package/src/runs/shared/agent-contract.d.ts +6 -0
- package/src/runs/shared/agent-contract.d.ts.map +1 -0
- package/src/runs/shared/agent-contract.js +36 -0
- package/src/runs/shared/agent-contract.js.map +1 -0
- package/src/runs/shared/async-status-projection.d.ts +94 -0
- package/src/runs/shared/async-status-projection.d.ts.map +1 -0
- package/src/runs/shared/async-status-projection.js +542 -0
- package/src/runs/shared/async-status-projection.js.map +1 -0
- package/src/runs/shared/background-process-options.d.ts +5 -0
- package/src/runs/shared/background-process-options.d.ts.map +1 -0
- package/src/runs/shared/background-process-options.js +7 -0
- package/src/runs/shared/background-process-options.js.map +1 -0
- package/src/runs/shared/capability-ceiling.d.ts +58 -0
- package/src/runs/shared/capability-ceiling.d.ts.map +1 -0
- package/src/runs/shared/capability-ceiling.js +179 -0
- package/src/runs/shared/capability-ceiling.js.map +1 -0
- package/src/runs/shared/chain-outputs.d.ts +19 -0
- package/src/runs/shared/chain-outputs.d.ts.map +1 -0
- package/src/runs/shared/chain-outputs.js +105 -0
- package/src/runs/shared/chain-outputs.js.map +1 -0
- package/src/runs/shared/child-hooks.d.ts +34 -0
- package/src/runs/shared/child-hooks.d.ts.map +1 -0
- package/src/runs/shared/child-hooks.js +188 -0
- package/src/runs/shared/child-hooks.js.map +1 -0
- package/src/runs/shared/child-identity.d.ts +24 -0
- package/src/runs/shared/child-identity.d.ts.map +1 -0
- package/src/runs/shared/child-identity.js +41 -0
- package/src/runs/shared/child-identity.js.map +1 -0
- package/src/runs/shared/child-launch-plan.d.ts +71 -0
- package/src/runs/shared/child-launch-plan.d.ts.map +1 -0
- package/src/runs/shared/child-launch-plan.js +89 -0
- package/src/runs/shared/child-launch-plan.js.map +1 -0
- package/src/runs/shared/child-launch.d.ts +114 -0
- package/src/runs/shared/child-launch.d.ts.map +1 -0
- package/src/runs/shared/child-launch.js +231 -0
- package/src/runs/shared/child-launch.js.map +1 -0
- package/src/runs/shared/child-lifecycle.d.ts +14 -0
- package/src/runs/shared/child-lifecycle.d.ts.map +1 -0
- package/src/runs/shared/child-lifecycle.js +23 -0
- package/src/runs/shared/child-lifecycle.js.map +1 -0
- package/src/runs/shared/child-runtime-config.d.ts +102 -0
- package/src/runs/shared/child-runtime-config.d.ts.map +1 -0
- package/src/runs/shared/child-runtime-config.js +39 -0
- package/src/runs/shared/child-runtime-config.js.map +1 -0
- package/src/runs/shared/child-session.d.ts +155 -0
- package/src/runs/shared/child-session.d.ts.map +1 -0
- package/src/runs/shared/child-session.js +347 -0
- package/src/runs/shared/child-session.js.map +1 -0
- package/src/runs/shared/child-tool-plan.d.ts +73 -0
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -0
- package/src/runs/shared/child-tool-plan.js +380 -0
- package/src/runs/shared/child-tool-plan.js.map +1 -0
- package/src/runs/shared/claude-code-adapter.d.ts +25 -0
- package/src/runs/shared/claude-code-adapter.d.ts.map +1 -0
- package/src/runs/shared/claude-code-adapter.js +120 -0
- package/src/runs/shared/claude-code-adapter.js.map +1 -0
- package/src/runs/shared/codex-exec-adapter.d.ts +26 -0
- package/src/runs/shared/codex-exec-adapter.d.ts.map +1 -0
- package/src/runs/shared/codex-exec-adapter.js +128 -0
- package/src/runs/shared/codex-exec-adapter.js.map +1 -0
- package/src/runs/shared/completion-evidence.d.ts +31 -0
- package/src/runs/shared/completion-evidence.d.ts.map +1 -0
- package/src/runs/shared/completion-evidence.js +54 -0
- package/src/runs/shared/completion-evidence.js.map +1 -0
- package/src/runs/shared/completion-guard.d.ts +35 -0
- package/src/runs/shared/completion-guard.d.ts.map +1 -0
- package/src/runs/shared/completion-guard.js +214 -0
- package/src/runs/shared/completion-guard.js.map +1 -0
- package/src/runs/shared/context-mode.d.ts +13 -0
- package/src/runs/shared/context-mode.d.ts.map +1 -0
- package/src/runs/shared/context-mode.js +39 -0
- package/src/runs/shared/context-mode.js.map +1 -0
- package/src/runs/shared/cursor-agent-adapter.d.ts +27 -0
- package/src/runs/shared/cursor-agent-adapter.d.ts.map +1 -0
- package/src/runs/shared/cursor-agent-adapter.js +100 -0
- package/src/runs/shared/cursor-agent-adapter.js.map +1 -0
- package/src/runs/shared/dynamic-fanout.d.ts +50 -0
- package/src/runs/shared/dynamic-fanout.d.ts.map +1 -0
- package/src/runs/shared/dynamic-fanout.js +274 -0
- package/src/runs/shared/dynamic-fanout.js.map +1 -0
- package/src/runs/shared/effective-system-prompt.d.ts +18 -0
- package/src/runs/shared/effective-system-prompt.d.ts.map +1 -0
- package/src/runs/shared/effective-system-prompt.js +23 -0
- package/src/runs/shared/effective-system-prompt.js.map +1 -0
- package/src/runs/shared/extension-bindings.d.ts +17 -0
- package/src/runs/shared/extension-bindings.d.ts.map +1 -0
- package/src/runs/shared/extension-bindings.js +83 -0
- package/src/runs/shared/extension-bindings.js.map +1 -0
- package/src/runs/shared/external-cli-contract.d.ts +30 -0
- package/src/runs/shared/external-cli-contract.d.ts.map +1 -0
- package/src/runs/shared/external-cli-contract.js +146 -0
- package/src/runs/shared/external-cli-contract.js.map +1 -0
- package/src/runs/shared/external-cli-preflight.d.ts +32 -0
- package/src/runs/shared/external-cli-preflight.d.ts.map +1 -0
- package/src/runs/shared/external-cli-preflight.js +116 -0
- package/src/runs/shared/external-cli-preflight.js.map +1 -0
- package/src/runs/shared/external-cli-runner.d.ts +66 -0
- package/src/runs/shared/external-cli-runner.d.ts.map +1 -0
- package/src/runs/shared/external-cli-runner.js +421 -0
- package/src/runs/shared/external-cli-runner.js.map +1 -0
- package/src/runs/shared/external-job-bridge.d.ts +18 -0
- package/src/runs/shared/external-job-bridge.d.ts.map +1 -0
- package/src/runs/shared/external-job-bridge.js +424 -0
- package/src/runs/shared/external-job-bridge.js.map +1 -0
- package/src/runs/shared/external-job-runner.d.ts +45 -0
- package/src/runs/shared/external-job-runner.d.ts.map +1 -0
- package/src/runs/shared/external-job-runner.js +353 -0
- package/src/runs/shared/external-job-runner.js.map +1 -0
- package/src/runs/shared/fast-mode-extension.d.ts +4 -0
- package/src/runs/shared/fast-mode-extension.d.ts.map +1 -0
- package/src/runs/shared/fast-mode-extension.js +9 -0
- package/src/runs/shared/fast-mode-extension.js.map +1 -0
- package/src/runs/shared/herdr-connection.d.ts +71 -0
- package/src/runs/shared/herdr-connection.d.ts.map +1 -0
- package/src/runs/shared/herdr-connection.js +258 -0
- package/src/runs/shared/herdr-connection.js.map +1 -0
- package/src/runs/shared/herdr-external-adapters.d.ts +148 -0
- package/src/runs/shared/herdr-external-adapters.d.ts.map +1 -0
- package/src/runs/shared/herdr-external-adapters.js +405 -0
- package/src/runs/shared/herdr-external-adapters.js.map +1 -0
- package/src/runs/shared/herdr-machine.d.ts +48 -0
- package/src/runs/shared/herdr-machine.d.ts.map +1 -0
- package/src/runs/shared/herdr-machine.js +247 -0
- package/src/runs/shared/herdr-machine.js.map +1 -0
- package/src/runs/shared/herdr-pi-protocol.d.ts +22 -0
- package/src/runs/shared/herdr-pi-protocol.d.ts.map +1 -0
- package/src/runs/shared/herdr-pi-protocol.js +58 -0
- package/src/runs/shared/herdr-pi-protocol.js.map +1 -0
- package/src/runs/shared/herdr-placed-run.d.ts +267 -0
- package/src/runs/shared/herdr-placed-run.d.ts.map +1 -0
- package/src/runs/shared/herdr-placed-run.js +716 -0
- package/src/runs/shared/herdr-placed-run.js.map +1 -0
- package/src/runs/shared/host-step-status.d.ts +34 -0
- package/src/runs/shared/host-step-status.d.ts.map +1 -0
- package/src/runs/shared/host-step-status.js +245 -0
- package/src/runs/shared/host-step-status.js.map +1 -0
- package/src/runs/shared/lane-metadata.d.ts +24 -0
- package/src/runs/shared/lane-metadata.d.ts.map +1 -0
- package/src/runs/shared/lane-metadata.js +127 -0
- package/src/runs/shared/lane-metadata.js.map +1 -0
- package/src/runs/shared/launch-cwd.d.ts +2 -0
- package/src/runs/shared/launch-cwd.d.ts.map +1 -0
- package/src/runs/shared/launch-cwd.js +17 -0
- package/src/runs/shared/launch-cwd.js.map +1 -0
- package/src/runs/shared/llm-intent-arbiter.d.ts +48 -0
- package/src/runs/shared/llm-intent-arbiter.d.ts.map +1 -0
- package/src/runs/shared/llm-intent-arbiter.js +235 -0
- package/src/runs/shared/llm-intent-arbiter.js.map +1 -0
- package/src/runs/shared/long-running-guard.d.ts +33 -0
- package/src/runs/shared/long-running-guard.d.ts.map +1 -0
- package/src/runs/shared/long-running-guard.js +199 -0
- package/src/runs/shared/long-running-guard.js.map +1 -0
- package/src/runs/shared/mcp-config-sources.d.ts +30 -0
- package/src/runs/shared/mcp-config-sources.d.ts.map +1 -0
- package/src/runs/shared/mcp-config-sources.js +419 -0
- package/src/runs/shared/mcp-config-sources.js.map +1 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.d.ts +59 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.d.ts.map +1 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.js +400 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -0
- package/src/runs/shared/mcp-direct-tool-grant.d.ts +41 -0
- package/src/runs/shared/mcp-direct-tool-grant.d.ts.map +1 -0
- package/src/runs/shared/mcp-direct-tool-grant.js +146 -0
- package/src/runs/shared/mcp-direct-tool-grant.js.map +1 -0
- package/src/runs/shared/model-resolution-diagnostic.d.ts +22 -0
- package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -0
- package/src/runs/shared/model-resolution-diagnostic.js +65 -0
- package/src/runs/shared/model-resolution-diagnostic.js.map +1 -0
- package/src/runs/shared/model-resolution.d.ts +92 -0
- package/src/runs/shared/model-resolution.d.ts.map +1 -0
- package/src/runs/shared/model-resolution.js +343 -0
- package/src/runs/shared/model-resolution.js.map +1 -0
- package/src/runs/shared/model-scope.d.ts +68 -0
- package/src/runs/shared/model-scope.d.ts.map +1 -0
- package/src/runs/shared/model-scope.js +156 -0
- package/src/runs/shared/model-scope.js.map +1 -0
- package/src/runs/shared/mutation-evidence.d.ts +19 -0
- package/src/runs/shared/mutation-evidence.d.ts.map +1 -0
- package/src/runs/shared/mutation-evidence.js +199 -0
- package/src/runs/shared/mutation-evidence.js.map +1 -0
- package/src/runs/shared/nested-events.d.ts +134 -0
- package/src/runs/shared/nested-events.d.ts.map +1 -0
- package/src/runs/shared/nested-events.js +1056 -0
- package/src/runs/shared/nested-events.js.map +1 -0
- package/src/runs/shared/nested-path.d.ts +9 -0
- package/src/runs/shared/nested-path.d.ts.map +1 -0
- package/src/runs/shared/nested-path.js +35 -0
- package/src/runs/shared/nested-path.js.map +1 -0
- package/src/runs/shared/nested-render.d.ts +21 -0
- package/src/runs/shared/nested-render.d.ts.map +1 -0
- package/src/runs/shared/nested-render.js +116 -0
- package/src/runs/shared/nested-render.js.map +1 -0
- package/src/runs/shared/orca-progress-tabs.d.ts +33 -0
- package/src/runs/shared/orca-progress-tabs.d.ts.map +1 -0
- package/src/runs/shared/orca-progress-tabs.js +527 -0
- package/src/runs/shared/orca-progress-tabs.js.map +1 -0
- package/src/runs/shared/parallel-handoff.d.ts +73 -0
- package/src/runs/shared/parallel-handoff.d.ts.map +1 -0
- package/src/runs/shared/parallel-handoff.js +733 -0
- package/src/runs/shared/parallel-handoff.js.map +1 -0
- package/src/runs/shared/parallel-utils.d.ts +165 -0
- package/src/runs/shared/parallel-utils.d.ts.map +1 -0
- package/src/runs/shared/parallel-utils.js +126 -0
- package/src/runs/shared/parallel-utils.js.map +1 -0
- package/src/runs/shared/permissions.d.ts +13 -0
- package/src/runs/shared/permissions.d.ts.map +1 -0
- package/src/runs/shared/permissions.js +93 -0
- package/src/runs/shared/permissions.js.map +1 -0
- package/src/runs/shared/pi-spawn.d.ts +28 -0
- package/src/runs/shared/pi-spawn.d.ts.map +1 -0
- package/src/runs/shared/pi-spawn.js +156 -0
- package/src/runs/shared/pi-spawn.js.map +1 -0
- package/src/runs/shared/process-signal.d.ts +16 -0
- package/src/runs/shared/process-signal.d.ts.map +1 -0
- package/src/runs/shared/process-signal.js +22 -0
- package/src/runs/shared/process-signal.js.map +1 -0
- package/src/runs/shared/readonly-drain-observation.d.ts +26 -0
- package/src/runs/shared/readonly-drain-observation.d.ts.map +1 -0
- package/src/runs/shared/readonly-drain-observation.js +51 -0
- package/src/runs/shared/readonly-drain-observation.js.map +1 -0
- package/src/runs/shared/run-fanout-budget.d.ts +15 -0
- package/src/runs/shared/run-fanout-budget.d.ts.map +1 -0
- package/src/runs/shared/run-fanout-budget.js +259 -0
- package/src/runs/shared/run-fanout-budget.js.map +1 -0
- package/src/runs/shared/run-history.d.ts +20 -0
- package/src/runs/shared/run-history.d.ts.map +1 -0
- package/src/runs/shared/run-history.js +200 -0
- package/src/runs/shared/run-history.js.map +1 -0
- package/src/runs/shared/runtime-acknowledged-extensions.d.ts +8 -0
- package/src/runs/shared/runtime-acknowledged-extensions.d.ts.map +1 -0
- package/src/runs/shared/runtime-acknowledged-extensions.js +45 -0
- package/src/runs/shared/runtime-acknowledged-extensions.js.map +1 -0
- package/src/runs/shared/session-lease.d.ts +70 -0
- package/src/runs/shared/session-lease.d.ts.map +1 -0
- package/src/runs/shared/session-lease.js +251 -0
- package/src/runs/shared/session-lease.js.map +1 -0
- package/src/runs/shared/single-output.d.ts +61 -0
- package/src/runs/shared/single-output.d.ts.map +1 -0
- package/src/runs/shared/single-output.js +263 -0
- package/src/runs/shared/single-output.js.map +1 -0
- package/src/runs/shared/spawn-budget.d.ts +21 -0
- package/src/runs/shared/spawn-budget.d.ts.map +1 -0
- package/src/runs/shared/spawn-budget.js +94 -0
- package/src/runs/shared/spawn-budget.js.map +1 -0
- package/src/runs/shared/structured-output.d.ts +57 -0
- package/src/runs/shared/structured-output.d.ts.map +1 -0
- package/src/runs/shared/structured-output.js +391 -0
- package/src/runs/shared/structured-output.js.map +1 -0
- package/src/runs/shared/subagent-control.d.ts +50 -0
- package/src/runs/shared/subagent-control.d.ts.map +1 -0
- package/src/runs/shared/subagent-control.js +247 -0
- package/src/runs/shared/subagent-control.js.map +1 -0
- package/src/runs/shared/subagent-prompt-runtime.d.ts +28 -0
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -0
- package/src/runs/shared/subagent-prompt-runtime.js +548 -0
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -0
- package/src/runs/shared/task-intent.d.ts +38 -0
- package/src/runs/shared/task-intent.d.ts.map +1 -0
- package/src/runs/shared/task-intent.js +213 -0
- package/src/runs/shared/task-intent.js.map +1 -0
- package/src/runs/shared/tool-availability.d.ts +17 -0
- package/src/runs/shared/tool-availability.d.ts.map +1 -0
- package/src/runs/shared/tool-availability.js +30 -0
- package/src/runs/shared/tool-availability.js.map +1 -0
- package/src/runs/shared/tool-budget.d.ts +22 -0
- package/src/runs/shared/tool-budget.d.ts.map +1 -0
- package/src/runs/shared/tool-budget.js +79 -0
- package/src/runs/shared/tool-budget.js.map +1 -0
- package/src/runs/shared/tool-timeout.d.ts +32 -0
- package/src/runs/shared/tool-timeout.d.ts.map +1 -0
- package/src/runs/shared/tool-timeout.js +74 -0
- package/src/runs/shared/tool-timeout.js.map +1 -0
- package/src/runs/shared/usage-budget.d.ts +8 -0
- package/src/runs/shared/usage-budget.d.ts.map +1 -0
- package/src/runs/shared/usage-budget.js +75 -0
- package/src/runs/shared/usage-budget.js.map +1 -0
- package/src/runs/shared/usage-reconciliation.d.ts +9 -0
- package/src/runs/shared/usage-reconciliation.d.ts.map +1 -0
- package/src/runs/shared/usage-reconciliation.js +72 -0
- package/src/runs/shared/usage-reconciliation.js.map +1 -0
- package/src/runs/shared/workflow-async-child-guidance.d.ts +4 -0
- package/src/runs/shared/workflow-async-child-guidance.d.ts.map +1 -0
- package/src/runs/shared/workflow-async-child-guidance.js +18 -0
- package/src/runs/shared/workflow-async-child-guidance.js.map +1 -0
- package/src/runs/shared/workflow-graph.d.ts +32 -0
- package/src/runs/shared/workflow-graph.d.ts.map +1 -0
- package/src/runs/shared/workflow-graph.js +222 -0
- package/src/runs/shared/workflow-graph.js.map +1 -0
- package/src/runs/shared/worktree-cleanup-plan.d.ts +78 -0
- package/src/runs/shared/worktree-cleanup-plan.d.ts.map +1 -0
- package/src/runs/shared/worktree-cleanup-plan.js +782 -0
- package/src/runs/shared/worktree-cleanup-plan.js.map +1 -0
- package/src/runs/shared/worktree-setup-command.d.ts +39 -0
- package/src/runs/shared/worktree-setup-command.d.ts.map +1 -0
- package/src/runs/shared/worktree-setup-command.js +201 -0
- package/src/runs/shared/worktree-setup-command.js.map +1 -0
- package/src/runs/shared/worktree.d.ts +179 -0
- package/src/runs/shared/worktree.d.ts.map +1 -0
- package/src/runs/shared/worktree.js +1333 -0
- package/src/runs/shared/worktree.js.map +1 -0
- package/src/shared/accessible-dir.d.ts +12 -0
- package/src/shared/accessible-dir.d.ts.map +1 -0
- package/src/shared/accessible-dir.js +37 -0
- package/src/shared/accessible-dir.js.map +1 -0
- package/src/shared/agent-stream-options.d.ts +6 -0
- package/src/shared/agent-stream-options.d.ts.map +1 -0
- package/src/shared/agent-stream-options.js +4 -0
- package/src/shared/agent-stream-options.js.map +1 -0
- package/src/shared/artifacts.d.ts +23 -0
- package/src/shared/artifacts.d.ts.map +1 -0
- package/src/shared/artifacts.js +273 -0
- package/src/shared/artifacts.js.map +1 -0
- package/src/shared/atomic-json.d.ts +19 -0
- package/src/shared/atomic-json.d.ts.map +1 -0
- package/src/shared/atomic-json.js +60 -0
- package/src/shared/atomic-json.js.map +1 -0
- package/src/shared/capacity-resilient-json.d.ts +27 -0
- package/src/shared/capacity-resilient-json.d.ts.map +1 -0
- package/src/shared/capacity-resilient-json.js +87 -0
- package/src/shared/capacity-resilient-json.js.map +1 -0
- package/src/shared/child-cache-retention.d.ts +30 -0
- package/src/shared/child-cache-retention.d.ts.map +1 -0
- package/src/shared/child-cache-retention.js +41 -0
- package/src/shared/child-cache-retention.js.map +1 -0
- package/src/shared/child-session-name.d.ts +9 -0
- package/src/shared/child-session-name.d.ts.map +1 -0
- package/src/shared/child-session-name.js +39 -0
- package/src/shared/child-session-name.js.map +1 -0
- package/src/shared/child-transcript.d.ts +38 -0
- package/src/shared/child-transcript.d.ts.map +1 -0
- package/src/shared/child-transcript.js +226 -0
- package/src/shared/child-transcript.js.map +1 -0
- package/src/shared/completion-owner.d.ts +3 -0
- package/src/shared/completion-owner.d.ts.map +1 -0
- package/src/shared/completion-owner.js +9 -0
- package/src/shared/completion-owner.js.map +1 -0
- package/src/shared/display-text.d.ts +6 -0
- package/src/shared/display-text.d.ts.map +1 -0
- package/src/shared/display-text.js +155 -0
- package/src/shared/display-text.js.map +1 -0
- package/src/shared/extension-context.d.ts +6 -0
- package/src/shared/extension-context.d.ts.map +1 -0
- package/src/shared/extension-context.js +22 -0
- package/src/shared/extension-context.js.map +1 -0
- package/src/shared/file-coalescer.d.ts +12 -0
- package/src/shared/file-coalescer.d.ts.map +1 -0
- package/src/shared/file-coalescer.js +35 -0
- package/src/shared/file-coalescer.js.map +1 -0
- package/src/shared/file-system-retry.d.ts +32 -0
- package/src/shared/file-system-retry.d.ts.map +1 -0
- package/src/shared/file-system-retry.js +85 -0
- package/src/shared/file-system-retry.js.map +1 -0
- package/src/shared/fork-context.d.ts +59 -0
- package/src/shared/fork-context.d.ts.map +1 -0
- package/src/shared/fork-context.js +171 -0
- package/src/shared/fork-context.js.map +1 -0
- package/src/shared/fork-session-cwd.d.ts +3 -0
- package/src/shared/fork-session-cwd.d.ts.map +1 -0
- package/src/shared/fork-session-cwd.js +24 -0
- package/src/shared/fork-session-cwd.js.map +1 -0
- package/src/shared/formatters.d.ts +36 -0
- package/src/shared/formatters.d.ts.map +1 -0
- package/src/shared/formatters.js +143 -0
- package/src/shared/formatters.js.map +1 -0
- package/src/shared/jsonl-writer.d.ts +21 -0
- package/src/shared/jsonl-writer.d.ts.map +1 -0
- package/src/shared/jsonl-writer.js +68 -0
- package/src/shared/jsonl-writer.js.map +1 -0
- package/src/shared/launch-contract.d.ts +64 -0
- package/src/shared/launch-contract.d.ts.map +1 -0
- package/src/shared/launch-contract.js +141 -0
- package/src/shared/launch-contract.js.map +1 -0
- package/src/shared/model-info.d.ts +44 -0
- package/src/shared/model-info.d.ts.map +1 -0
- package/src/shared/model-info.js +73 -0
- package/src/shared/model-info.js.map +1 -0
- package/src/shared/model-response-aliases.d.ts +2 -0
- package/src/shared/model-response-aliases.d.ts.map +1 -0
- package/src/shared/model-response-aliases.js +16 -0
- package/src/shared/model-response-aliases.js.map +1 -0
- package/src/shared/node-executable.d.ts +2 -0
- package/src/shared/node-executable.d.ts.map +1 -0
- package/src/shared/node-executable.js +21 -0
- package/src/shared/node-executable.js.map +1 -0
- package/src/shared/opencode-session-headers.d.ts +13 -0
- package/src/shared/opencode-session-headers.d.ts.map +1 -0
- package/src/shared/opencode-session-headers.js +27 -0
- package/src/shared/opencode-session-headers.js.map +1 -0
- package/src/shared/prompt-resources.d.ts +6 -0
- package/src/shared/prompt-resources.d.ts.map +1 -0
- package/src/shared/prompt-resources.js +11 -0
- package/src/shared/prompt-resources.js.map +1 -0
- package/src/shared/pruned-fork.d.ts +35 -0
- package/src/shared/pruned-fork.d.ts.map +1 -0
- package/src/shared/pruned-fork.js +424 -0
- package/src/shared/pruned-fork.js.map +1 -0
- package/src/shared/required-child-extensions.d.ts +20 -0
- package/src/shared/required-child-extensions.d.ts.map +1 -0
- package/src/shared/required-child-extensions.js +74 -0
- package/src/shared/required-child-extensions.js.map +1 -0
- package/src/shared/session-file-trust.d.ts +2 -0
- package/src/shared/session-file-trust.d.ts.map +1 -0
- package/src/shared/session-file-trust.js +21 -0
- package/src/shared/session-file-trust.js.map +1 -0
- package/src/shared/session-identity.d.ts +7 -0
- package/src/shared/session-identity.d.ts.map +1 -0
- package/src/shared/session-identity.js +7 -0
- package/src/shared/session-identity.js.map +1 -0
- package/src/shared/session-tokens.d.ts +3 -0
- package/src/shared/session-tokens.d.ts.map +1 -0
- package/src/shared/session-tokens.js +59 -0
- package/src/shared/session-tokens.js.map +1 -0
- package/src/shared/settings.d.ts +147 -0
- package/src/shared/settings.d.ts.map +1 -0
- package/src/shared/settings.js +248 -0
- package/src/shared/settings.js.map +1 -0
- package/src/shared/shortcuts.d.ts +2 -0
- package/src/shared/shortcuts.d.ts.map +1 -0
- package/src/shared/shortcuts.js +18 -0
- package/src/shared/shortcuts.js.map +1 -0
- package/src/shared/status-format.d.ts +10 -0
- package/src/shared/status-format.d.ts.map +1 -0
- package/src/shared/status-format.js +61 -0
- package/src/shared/status-format.js.map +1 -0
- package/src/shared/thinking-ceiling.d.ts +14 -0
- package/src/shared/thinking-ceiling.d.ts.map +1 -0
- package/src/shared/thinking-ceiling.js +38 -0
- package/src/shared/thinking-ceiling.js.map +1 -0
- package/src/shared/types.d.ts +2667 -0
- package/src/shared/types.d.ts.map +1 -0
- package/src/shared/types.js +265 -0
- package/src/shared/types.js.map +1 -0
- package/src/shared/utf8.d.ts +6 -0
- package/src/shared/utf8.d.ts.map +1 -0
- package/src/shared/utf8.js +13 -0
- package/src/shared/utf8.js.map +1 -0
- package/src/shared/utils.d.ts +71 -0
- package/src/shared/utils.d.ts.map +1 -0
- package/src/shared/utils.js +593 -0
- package/src/shared/utils.js.map +1 -0
- package/src/shared/watch-strategy.d.ts +3 -0
- package/src/shared/watch-strategy.d.ts.map +1 -0
- package/src/shared/watch-strategy.js +6 -0
- package/src/shared/watch-strategy.js.map +1 -0
- package/src/shared/workflow-child-permit.d.ts +59 -0
- package/src/shared/workflow-child-permit.d.ts.map +1 -0
- package/src/shared/workflow-child-permit.js +160 -0
- package/src/shared/workflow-child-permit.js.map +1 -0
- package/src/slash/delegation-adapters.d.ts +147 -0
- package/src/slash/delegation-adapters.d.ts.map +1 -0
- package/src/slash/delegation-adapters.js +293 -0
- package/src/slash/delegation-adapters.js.map +1 -0
- package/src/slash/delegation-json.d.ts +11 -0
- package/src/slash/delegation-json.d.ts.map +1 -0
- package/src/slash/delegation-json.js +118 -0
- package/src/slash/delegation-json.js.map +1 -0
- package/src/slash/delegation-request.d.ts +13 -0
- package/src/slash/delegation-request.d.ts.map +1 -0
- package/src/slash/delegation-request.js +175 -0
- package/src/slash/delegation-request.js.map +1 -0
- package/src/slash/prompt-template-bridge.d.ts +27 -0
- package/src/slash/prompt-template-bridge.d.ts.map +1 -0
- package/src/slash/prompt-template-bridge.js +380 -0
- package/src/slash/prompt-template-bridge.js.map +1 -0
- package/src/slash/prompt-workflows.d.ts +22 -0
- package/src/slash/prompt-workflows.d.ts.map +1 -0
- package/src/slash/prompt-workflows.js +261 -0
- package/src/slash/prompt-workflows.js.map +1 -0
- package/src/slash/selector.d.ts +48 -0
- package/src/slash/selector.d.ts.map +1 -0
- package/src/slash/selector.js +118 -0
- package/src/slash/selector.js.map +1 -0
- package/src/slash/slash-bridge.d.ts +31 -0
- package/src/slash/slash-bridge.d.ts.map +1 -0
- package/src/slash/slash-bridge.js +133 -0
- package/src/slash/slash-bridge.js.map +1 -0
- package/src/slash/slash-commands.d.ts +9 -0
- package/src/slash/slash-commands.d.ts.map +1 -0
- package/src/slash/slash-commands.js +1295 -0
- package/src/slash/slash-commands.js.map +1 -0
- package/src/slash/slash-live-state.d.ts +22 -0
- package/src/slash/slash-live-state.d.ts.map +1 -0
- package/src/slash/slash-live-state.js +264 -0
- package/src/slash/slash-live-state.js.map +1 -0
- package/src/slash/subagents-admin.d.ts +3 -0
- package/src/slash/subagents-admin.d.ts.map +1 -0
- package/src/slash/subagents-admin.js +454 -0
- package/src/slash/subagents-admin.js.map +1 -0
- package/src/tui/fleet-status.d.ts +86 -0
- package/src/tui/fleet-status.d.ts.map +1 -0
- package/src/tui/fleet-status.js +1083 -0
- package/src/tui/fleet-status.js.map +1 -0
- package/src/tui/fleet-transcript.d.ts +50 -0
- package/src/tui/fleet-transcript.d.ts.map +1 -0
- package/src/tui/fleet-transcript.js +497 -0
- package/src/tui/fleet-transcript.js.map +1 -0
- package/src/tui/fleet.d.ts +169 -0
- package/src/tui/fleet.d.ts.map +1 -0
- package/src/tui/fleet.js +1412 -0
- package/src/tui/fleet.js.map +1 -0
- package/src/tui/render-helpers.d.ts +24 -0
- package/src/tui/render-helpers.d.ts.map +1 -0
- package/src/tui/render-helpers.js +101 -0
- package/src/tui/render-helpers.js.map +1 -0
- package/src/tui/render.d.ts +61 -0
- package/src/tui/render.d.ts.map +1 -0
- package/src/tui/render.js +3607 -0
- package/src/tui/render.js.map +1 -0
- package/src/watchdog/change-signature.d.ts +8 -0
- package/src/watchdog/change-signature.d.ts.map +1 -0
- package/src/watchdog/change-signature.js +246 -0
- package/src/watchdog/change-signature.js.map +1 -0
- package/src/watchdog/child-status.d.ts +54 -0
- package/src/watchdog/child-status.d.ts.map +1 -0
- package/src/watchdog/child-status.js +188 -0
- package/src/watchdog/child-status.js.map +1 -0
- package/src/watchdog/diff-tool.d.ts +23 -0
- package/src/watchdog/diff-tool.d.ts.map +1 -0
- package/src/watchdog/diff-tool.js +84 -0
- package/src/watchdog/diff-tool.js.map +1 -0
- package/src/watchdog/emission-guard.d.ts +37 -0
- package/src/watchdog/emission-guard.d.ts.map +1 -0
- package/src/watchdog/emission-guard.js +98 -0
- package/src/watchdog/emission-guard.js.map +1 -0
- package/src/watchdog/guidance.d.ts +4 -0
- package/src/watchdog/guidance.d.ts.map +1 -0
- package/src/watchdog/guidance.js +20 -0
- package/src/watchdog/guidance.js.map +1 -0
- package/src/watchdog/lsp-diagnostics.d.ts +18 -0
- package/src/watchdog/lsp-diagnostics.d.ts.map +1 -0
- package/src/watchdog/lsp-diagnostics.js +490 -0
- package/src/watchdog/lsp-diagnostics.js.map +1 -0
- package/src/watchdog/model-selection.d.ts +25 -0
- package/src/watchdog/model-selection.d.ts.map +1 -0
- package/src/watchdog/model-selection.js +168 -0
- package/src/watchdog/model-selection.js.map +1 -0
- package/src/watchdog/permission-arbiter.d.ts +21 -0
- package/src/watchdog/permission-arbiter.d.ts.map +1 -0
- package/src/watchdog/permission-arbiter.js +136 -0
- package/src/watchdog/permission-arbiter.js.map +1 -0
- package/src/watchdog/register-child.d.ts +12 -0
- package/src/watchdog/register-child.d.ts.map +1 -0
- package/src/watchdog/register-child.js +120 -0
- package/src/watchdog/register-child.js.map +1 -0
- package/src/watchdog/register-main.d.ts +10 -0
- package/src/watchdog/register-main.d.ts.map +1 -0
- package/src/watchdog/register-main.js +419 -0
- package/src/watchdog/register-main.js.map +1 -0
- package/src/watchdog/render.d.ts +12 -0
- package/src/watchdog/render.d.ts.map +1 -0
- package/src/watchdog/render.js +52 -0
- package/src/watchdog/render.js.map +1 -0
- package/src/watchdog/review.d.ts +36 -0
- package/src/watchdog/review.d.ts.map +1 -0
- package/src/watchdog/review.js +318 -0
- package/src/watchdog/review.js.map +1 -0
- package/src/watchdog/rules.d.ts +22 -0
- package/src/watchdog/rules.d.ts.map +1 -0
- package/src/watchdog/rules.js +59 -0
- package/src/watchdog/rules.js.map +1 -0
- package/src/watchdog/runtime.d.ts +196 -0
- package/src/watchdog/runtime.d.ts.map +1 -0
- package/src/watchdog/runtime.js +862 -0
- package/src/watchdog/runtime.js.map +1 -0
- package/src/watchdog/scope.d.ts +15 -0
- package/src/watchdog/scope.d.ts.map +1 -0
- package/src/watchdog/scope.js +45 -0
- package/src/watchdog/scope.js.map +1 -0
- package/src/watchdog/settings.d.ts +30 -0
- package/src/watchdog/settings.d.ts.map +1 -0
- package/src/watchdog/settings.js +476 -0
- package/src/watchdog/settings.js.map +1 -0
- package/src/watchdog/tool-actions.d.ts +18 -0
- package/src/watchdog/tool-actions.d.ts.map +1 -0
- package/src/watchdog/tool-actions.js +151 -0
- package/src/watchdog/tool-actions.js.map +1 -0
- package/src/watchdog/turn-delta.d.ts +12 -0
- package/src/watchdog/turn-delta.d.ts.map +1 -0
- package/src/watchdog/turn-delta.js +185 -0
- package/src/watchdog/turn-delta.js.map +1 -0
- package/src/watchdog/types.d.ts +142 -0
- package/src/watchdog/types.d.ts.map +1 -0
- package/src/watchdog/types.js +28 -0
- package/src/watchdog/types.js.map +1 -0
- package/src/watchdog/warning-format.d.ts +8 -0
- package/src/watchdog/warning-format.d.ts.map +1 -0
- package/src/watchdog/warning-format.js +60 -0
- package/src/watchdog/warning-format.js.map +1 -0
- package/src/workflows/chat-progress.d.ts +38 -0
- package/src/workflows/chat-progress.d.ts.map +1 -0
- package/src/workflows/chat-progress.js +130 -0
- package/src/workflows/chat-progress.js.map +1 -0
- package/src/workflows/host-command.d.ts +31 -0
- package/src/workflows/host-command.d.ts.map +1 -0
- package/src/workflows/host-command.js +228 -0
- package/src/workflows/host-command.js.map +1 -0
- package/src/workflows/scripted-workflow.d.ts +195 -0
- package/src/workflows/scripted-workflow.d.ts.map +1 -0
- package/src/workflows/scripted-workflow.js +2636 -0
- package/src/workflows/scripted-workflow.js.map +1 -0
- package/src/workflows/workflow-checklist.d.ts +124 -0
- package/src/workflows/workflow-checklist.d.ts.map +1 -0
- package/src/workflows/workflow-checklist.js +312 -0
- package/src/workflows/workflow-checklist.js.map +1 -0
- package/src/workflows/workflow-child-summary.d.ts +20 -0
- package/src/workflows/workflow-child-summary.d.ts.map +1 -0
- package/src/workflows/workflow-child-summary.js +179 -0
- package/src/workflows/workflow-child-summary.js.map +1 -0
- package/src/workflows/workflow-preflight.d.ts +59 -0
- package/src/workflows/workflow-preflight.d.ts.map +1 -0
- package/src/workflows/workflow-preflight.js +289 -0
- package/src/workflows/workflow-preflight.js.map +1 -0
- package/src/workflows/workflow-receipt.d.ts +35 -0
- package/src/workflows/workflow-receipt.d.ts.map +1 -0
- package/src/workflows/workflow-receipt.js +449 -0
- package/src/workflows/workflow-receipt.js.map +1 -0
- package/src/workflows/workflow-resources.d.ts +43 -0
- package/src/workflows/workflow-resources.d.ts.map +1 -0
- package/src/workflows/workflow-resources.js +230 -0
- package/src/workflows/workflow-resources.js.map +1 -0
- package/src/workflows/workflow-settlement.d.ts +85 -0
- package/src/workflows/workflow-settlement.d.ts.map +1 -0
- package/src/workflows/workflow-settlement.js +204 -0
- package/src/workflows/workflow-settlement.js.map +1 -0
- package/index.ts +0 -13
- package/src/agents/advertised-agent-prompt.ts +0 -94
- package/src/agents/agent-management.ts +0 -1417
- package/src/agents/agent-memory.ts +0 -254
- package/src/agents/agent-refinements.ts +0 -624
- package/src/agents/agent-scope.ts +0 -6
- package/src/agents/agent-selection.ts +0 -25
- package/src/agents/agent-serializer.ts +0 -182
- package/src/agents/agents.ts +0 -2917
- package/src/agents/builtin-names.ts +0 -16
- package/src/agents/chain-serializer.ts +0 -285
- package/src/agents/frontmatter.ts +0 -153
- package/src/agents/identity.ts +0 -30
- package/src/agents/proactive-skills.ts +0 -194
- package/src/agents/runtime-agent-events.ts +0 -70
- package/src/agents/runtime-agent-registry.ts +0 -430
- package/src/agents/skills.ts +0 -754
- package/src/api/agents.ts +0 -12
- package/src/api/background-work.ts +0 -206
- package/src/api/capability-ceiling.ts +0 -16
- package/src/api/child-tool-plan.ts +0 -5
- package/src/api/control-channel.ts +0 -4
- package/src/api/delegation.ts +0 -116
- package/src/api/external-job-provider.ts +0 -195
- package/src/api/external-runs.ts +0 -282
- package/src/api/intercom-bridge.ts +0 -3
- package/src/api/preflight.ts +0 -539
- package/src/api/project-panes.ts +0 -32
- package/src/api/required-child-extensions.ts +0 -6
- package/src/api/shared-types.ts +0 -29
- package/src/api/workflow-resources.ts +0 -6
- package/src/extension/config.ts +0 -230
- package/src/extension/control-notices.ts +0 -58
- package/src/extension/doctor.ts +0 -270
- package/src/extension/fanout-child.ts +0 -265
- package/src/extension/herdr-pi-bridge.ts +0 -160
- package/src/extension/index.ts +0 -1205
- package/src/extension/public-execution.ts +0 -225
- package/src/extension/rpc.ts +0 -848
- package/src/extension/schemas.ts +0 -428
- package/src/extension/steering-notices.ts +0 -35
- package/src/extension/subagent-guide.ts +0 -39
- package/src/extension/tool-description.ts +0 -175
- package/src/extension/tool-result.ts +0 -19
- package/src/inspectors/actions.ts +0 -148
- package/src/inspectors/ghostty/actions.ts +0 -74
- package/src/inspectors/ghostty/plugin.ts +0 -29
- package/src/inspectors/herdr/actions.ts +0 -155
- package/src/inspectors/herdr/client.ts +0 -130
- package/src/inspectors/herdr/focus.ts +0 -55
- package/src/inspectors/herdr/plugin.ts +0 -20
- package/src/inspectors/herdr/project-panes.ts +0 -730
- package/src/inspectors/inspector-runner.ts +0 -153
- package/src/inspectors/plugins.ts +0 -8
- package/src/inspectors/session-roots-codec.ts +0 -31
- package/src/inspectors/shell-command.ts +0 -16
- package/src/inspectors/types.ts +0 -51
- package/src/integrations/herdr-status.ts +0 -400
- package/src/integrations/pi-web-session-liveness.ts +0 -73
- package/src/intercom/intercom-bridge.ts +0 -233
- package/src/intercom/native-supervisor-channel.ts +0 -917
- package/src/intercom/result-intercom.ts +0 -423
- package/src/intercom/supervisor-ui.ts +0 -244
- package/src/missions/actions.ts +0 -433
- package/src/missions/goal-driver.ts +0 -164
- package/src/missions/lifecycle.ts +0 -367
- package/src/missions/store.ts +0 -584
- package/src/missions/types.ts +0 -190
- package/src/missions/workflow-state.ts +0 -281
- package/src/policy/authority.ts +0 -50
- package/src/profiles/profiles.ts +0 -668
- package/src/runs/background/active-async-capacity.ts +0 -520
- package/src/runs/background/active-run-index.ts +0 -155
- package/src/runs/background/async-execution.ts +0 -2278
- package/src/runs/background/async-job-tracker.ts +0 -826
- package/src/runs/background/async-resume.ts +0 -647
- package/src/runs/background/async-retention.ts +0 -912
- package/src/runs/background/async-status-snapshot.ts +0 -46
- package/src/runs/background/async-status.ts +0 -771
- package/src/runs/background/auto-drain.ts +0 -92
- package/src/runs/background/binary-bootstrap.ts +0 -38
- package/src/runs/background/chain-append.ts +0 -321
- package/src/runs/background/chain-root-attachment.ts +0 -259
- package/src/runs/background/completion-batcher.ts +0 -168
- package/src/runs/background/completion-dedupe.ts +0 -58
- package/src/runs/background/completion-replay.ts +0 -287
- package/src/runs/background/control-channel.ts +0 -600
- package/src/runs/background/fleet-view.ts +0 -648
- package/src/runs/background/index-segment.ts +0 -59
- package/src/runs/background/inspect-rpc.ts +0 -443
- package/src/runs/background/notify.ts +0 -819
- package/src/runs/background/owned-process-tree.ts +0 -131
- package/src/runs/background/parallel-groups.ts +0 -45
- package/src/runs/background/process-terminal.ts +0 -310
- package/src/runs/background/result-delivery-ownership.ts +0 -45
- package/src/runs/background/result-files.ts +0 -523
- package/src/runs/background/result-watcher.ts +0 -809
- package/src/runs/background/resume-guidance.ts +0 -56
- package/src/runs/background/retained-children.ts +0 -135
- package/src/runs/background/retained-nested-route-tracker.ts +0 -96
- package/src/runs/background/run-child-session.ts +0 -690
- package/src/runs/background/run-id-query.ts +0 -7
- package/src/runs/background/run-id-resolver.ts +0 -175
- package/src/runs/background/run-status.ts +0 -786
- package/src/runs/background/runner-aliases.ts +0 -142
- package/src/runs/background/runner-child-launch.ts +0 -91
- package/src/runs/background/runner-child-sessions.ts +0 -32
- package/src/runs/background/runner-http-dispatcher.ts +0 -119
- package/src/runs/background/scheduled-runs.ts +0 -1012
- package/src/runs/background/stale-run-reconciler.ts +0 -436
- package/src/runs/background/steering.ts +0 -260
- package/src/runs/background/subagent-runner.ts +0 -5357
- package/src/runs/background/subagent-wait.ts +0 -876
- package/src/runs/background/terminal-run-index.ts +0 -138
- package/src/runs/background/top-level-async.ts +0 -14
- package/src/runs/background/wait-completions.ts +0 -261
- package/src/runs/background/wait-config.ts +0 -50
- package/src/runs/background/wait-subscriptions.ts +0 -354
- package/src/runs/background/wait-tool.ts +0 -45
- package/src/runs/foreground/async-dismiss-action.ts +0 -86
- package/src/runs/foreground/async-steering-action.ts +0 -276
- package/src/runs/foreground/async-stop-action.ts +0 -176
- package/src/runs/foreground/execution.ts +0 -2254
- package/src/runs/foreground/foreground-control.ts +0 -157
- package/src/runs/foreground/foreground-history.ts +0 -163
- package/src/runs/foreground/prompt-audit.ts +0 -178
- package/src/runs/foreground/subagent-executor.ts +0 -7526
- package/src/runs/foreground/workflow-detach-reconcile.ts +0 -304
- package/src/runs/foreground/workflow-foreground-steering.ts +0 -169
- package/src/runs/shared/abort-recovery.ts +0 -119
- package/src/runs/shared/acceptance.ts +0 -1698
- package/src/runs/shared/agent-contract.ts +0 -38
- package/src/runs/shared/async-status-projection.ts +0 -659
- package/src/runs/shared/background-process-options.ts +0 -9
- package/src/runs/shared/capability-ceiling.ts +0 -211
- package/src/runs/shared/chain-outputs.ts +0 -116
- package/src/runs/shared/child-hooks.ts +0 -189
- package/src/runs/shared/child-identity.ts +0 -62
- package/src/runs/shared/child-launch-plan.ts +0 -163
- package/src/runs/shared/child-launch.ts +0 -342
- package/src/runs/shared/child-lifecycle.ts +0 -28
- package/src/runs/shared/child-runtime-config.ts +0 -133
- package/src/runs/shared/child-session.ts +0 -448
- package/src/runs/shared/child-tool-plan.ts +0 -661
- package/src/runs/shared/claude-code-adapter.ts +0 -133
- package/src/runs/shared/codex-exec-adapter.ts +0 -129
- package/src/runs/shared/completion-evidence.ts +0 -89
- package/src/runs/shared/completion-guard.ts +0 -255
- package/src/runs/shared/context-mode.ts +0 -44
- package/src/runs/shared/cursor-agent-adapter.ts +0 -114
- package/src/runs/shared/dynamic-fanout.ts +0 -297
- package/src/runs/shared/effective-system-prompt.ts +0 -33
- package/src/runs/shared/extension-bindings.ts +0 -78
- package/src/runs/shared/external-cli-contract.ts +0 -177
- package/src/runs/shared/external-cli-preflight.ts +0 -142
- package/src/runs/shared/external-cli-runner.ts +0 -431
- package/src/runs/shared/external-job-bridge.ts +0 -460
- package/src/runs/shared/external-job-runner.ts +0 -389
- package/src/runs/shared/fast-mode-extension.ts +0 -10
- package/src/runs/shared/herdr-connection.ts +0 -134
- package/src/runs/shared/herdr-external-adapters.ts +0 -169
- package/src/runs/shared/herdr-machine.ts +0 -279
- package/src/runs/shared/herdr-pi-protocol.ts +0 -59
- package/src/runs/shared/herdr-placed-run.ts +0 -263
- package/src/runs/shared/host-step-status.ts +0 -231
- package/src/runs/shared/lane-metadata.ts +0 -126
- package/src/runs/shared/launch-cwd.ts +0 -16
- package/src/runs/shared/llm-intent-arbiter.ts +0 -321
- package/src/runs/shared/long-running-guard.ts +0 -221
- package/src/runs/shared/mcp-config-sources.ts +0 -422
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -484
- package/src/runs/shared/mcp-direct-tool-grant.ts +0 -194
- package/src/runs/shared/model-resolution-diagnostic.ts +0 -76
- package/src/runs/shared/model-resolution.ts +0 -441
- package/src/runs/shared/model-scope.ts +0 -205
- package/src/runs/shared/mutation-evidence.ts +0 -199
- package/src/runs/shared/nested-events.ts +0 -1079
- package/src/runs/shared/nested-path.ts +0 -38
- package/src/runs/shared/nested-render.ts +0 -127
- package/src/runs/shared/orca-progress-tabs.ts +0 -510
- package/src/runs/shared/parallel-handoff.ts +0 -741
- package/src/runs/shared/parallel-utils.ts +0 -279
- package/src/runs/shared/permissions.ts +0 -86
- package/src/runs/shared/pi-spawn.ts +0 -207
- package/src/runs/shared/process-signal.ts +0 -35
- package/src/runs/shared/readonly-drain-observation.ts +0 -42
- package/src/runs/shared/run-fanout-budget.ts +0 -267
- package/src/runs/shared/run-history.ts +0 -201
- package/src/runs/shared/runtime-acknowledged-extensions.ts +0 -44
- package/src/runs/shared/session-lease.ts +0 -293
- package/src/runs/shared/single-output.ts +0 -304
- package/src/runs/shared/spawn-budget.ts +0 -128
- package/src/runs/shared/structured-output.ts +0 -236
- package/src/runs/shared/subagent-control.ts +0 -294
- package/src/runs/shared/subagent-prompt-runtime.ts +0 -545
- package/src/runs/shared/task-intent.ts +0 -244
- package/src/runs/shared/tool-availability.ts +0 -37
- package/src/runs/shared/tool-budget.ts +0 -66
- package/src/runs/shared/tool-timeout.ts +0 -93
- package/src/runs/shared/usage-budget.ts +0 -65
- package/src/runs/shared/workflow-async-child-guidance.ts +0 -18
- package/src/runs/shared/workflow-graph.ts +0 -225
- package/src/runs/shared/worktree-cleanup-plan.ts +0 -869
- package/src/runs/shared/worktree-setup-command.ts +0 -213
- package/src/runs/shared/worktree.ts +0 -1538
- package/src/shared/accessible-dir.ts +0 -47
- package/src/shared/agent-stream-options.ts +0 -5
- package/src/shared/artifacts.ts +0 -281
- package/src/shared/atomic-json.ts +0 -83
- package/src/shared/capacity-resilient-json.ts +0 -102
- package/src/shared/child-cache-retention.ts +0 -43
- package/src/shared/child-session-name.ts +0 -46
- package/src/shared/child-transcript.ts +0 -264
- package/src/shared/completion-owner.ts +0 -14
- package/src/shared/display-text.ts +0 -150
- package/src/shared/extension-context.ts +0 -24
- package/src/shared/file-coalescer.ts +0 -49
- package/src/shared/file-system-retry.ts +0 -95
- package/src/shared/fork-context.ts +0 -236
- package/src/shared/fork-session-cwd.ts +0 -27
- package/src/shared/formatters.ts +0 -146
- package/src/shared/jsonl-writer.ts +0 -92
- package/src/shared/launch-contract.ts +0 -198
- package/src/shared/model-info.ts +0 -101
- package/src/shared/model-response-aliases.ts +0 -13
- package/src/shared/node-executable.ts +0 -21
- package/src/shared/opencode-session-headers.ts +0 -30
- package/src/shared/prompt-resources.ts +0 -11
- package/src/shared/pruned-fork.ts +0 -450
- package/src/shared/required-child-extensions.ts +0 -81
- package/src/shared/session-file-trust.ts +0 -19
- package/src/shared/session-identity.ts +0 -10
- package/src/shared/session-tokens.ts +0 -55
- package/src/shared/settings.ts +0 -412
- package/src/shared/shortcuts.ts +0 -13
- package/src/shared/status-format.ts +0 -55
- package/src/shared/thinking-ceiling.ts +0 -46
- package/src/shared/types.ts +0 -2983
- package/src/shared/utf8.ts +0 -11
- package/src/shared/utils.ts +0 -608
- package/src/shared/watch-strategy.ts +0 -12
- package/src/shared/workflow-child-permit.ts +0 -212
- package/src/slash/delegation-adapters.ts +0 -428
- package/src/slash/delegation-json.ts +0 -108
- package/src/slash/delegation-request.ts +0 -176
- package/src/slash/prompt-template-bridge.ts +0 -419
- package/src/slash/prompt-workflows.ts +0 -287
- package/src/slash/selector.ts +0 -147
- package/src/slash/slash-bridge.ts +0 -192
- package/src/slash/slash-commands.ts +0 -1325
- package/src/slash/slash-live-state.ts +0 -310
- package/src/slash/subagents-admin.ts +0 -460
- package/src/tui/fleet-status.ts +0 -1109
- package/src/tui/fleet-transcript.ts +0 -536
- package/src/tui/fleet.ts +0 -1448
- package/src/tui/render-helpers.ts +0 -111
- package/src/tui/render.ts +0 -3721
- package/src/types/pi-runtime-compat.d.ts +0 -8
- package/src/watchdog/change-signature.ts +0 -260
- package/src/watchdog/child-status.ts +0 -225
- package/src/watchdog/diff-tool.ts +0 -77
- package/src/watchdog/emission-guard.ts +0 -125
- package/src/watchdog/guidance.ts +0 -20
- package/src/watchdog/lsp-diagnostics.ts +0 -538
- package/src/watchdog/model-selection.ts +0 -187
- package/src/watchdog/permission-arbiter.ts +0 -156
- package/src/watchdog/register-child.ts +0 -128
- package/src/watchdog/register-main.ts +0 -445
- package/src/watchdog/render.ts +0 -53
- package/src/watchdog/review.ts +0 -363
- package/src/watchdog/rules.ts +0 -70
- package/src/watchdog/runtime.ts +0 -924
- package/src/watchdog/scope.ts +0 -51
- package/src/watchdog/settings.ts +0 -515
- package/src/watchdog/tool-actions.ts +0 -156
- package/src/watchdog/turn-delta.ts +0 -184
- package/src/watchdog/types.ts +0 -186
- package/src/watchdog/warning-format.ts +0 -72
- package/src/workflows/chat-progress.ts +0 -152
- package/src/workflows/host-command.ts +0 -235
- package/src/workflows/scripted-workflow.ts +0 -2575
- package/src/workflows/workflow-checklist.ts +0 -436
- package/src/workflows/workflow-child-summary.ts +0 -170
- package/src/workflows/workflow-preflight.ts +0 -297
- package/src/workflows/workflow-receipt.ts +0 -384
- package/src/workflows/workflow-resources.ts +0 -236
- package/src/workflows/workflow-settlement.ts +0 -249
|
@@ -1,1698 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import * as path from "node:path";
|
|
6
|
-
import type {
|
|
7
|
-
AcceptanceConfig,
|
|
8
|
-
AcceptanceEvidenceKind,
|
|
9
|
-
AcceptanceInput,
|
|
10
|
-
AgentContract,
|
|
11
|
-
AcceptanceLedger,
|
|
12
|
-
AcceptanceLevel,
|
|
13
|
-
AcceptanceReport,
|
|
14
|
-
AcceptanceReviewGate,
|
|
15
|
-
AcceptanceRole,
|
|
16
|
-
AcceptanceRuntimeCheck,
|
|
17
|
-
AcceptanceRuntimeCheckStatus,
|
|
18
|
-
AcceptanceReviewResult,
|
|
19
|
-
AcceptanceVerifyCommand,
|
|
20
|
-
AcceptanceVerifyResult,
|
|
21
|
-
JsonSchemaObject,
|
|
22
|
-
ResolvedAcceptanceConfig,
|
|
23
|
-
ResolvedAcceptanceGate,
|
|
24
|
-
SingleResult,
|
|
25
|
-
SubagentRunMode,
|
|
26
|
-
ChildWatchdogProgress,
|
|
27
|
-
} from "../../shared/types.ts";
|
|
28
|
-
import { unresolvedChildWatchdogBlockers } from "../../watchdog/child-status.ts";
|
|
29
|
-
import { isAgentContract } from "./agent-contract.ts";
|
|
30
|
-
import { validateStructuredOutputValue } from "./structured-output.ts";
|
|
31
|
-
import { classifyTaskMutationIntent, stripSeverityCompounds, taskMayMutate } from "./task-intent.ts";
|
|
32
|
-
|
|
33
|
-
const LEVEL_RANK: Record<Exclude<AcceptanceLevel, "auto">, number> = {
|
|
34
|
-
none: 0,
|
|
35
|
-
attested: 1,
|
|
36
|
-
checked: 2,
|
|
37
|
-
verified: 3,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const VALID_LEVELS = new Set<AcceptanceLevel>(["auto", "none", "attested", "checked", "verified"]);
|
|
41
|
-
const VALID_EVIDENCE_KINDS: AcceptanceEvidenceKind[] = [
|
|
42
|
-
"changed-files",
|
|
43
|
-
"tests-added",
|
|
44
|
-
"commands-run",
|
|
45
|
-
"validation-output",
|
|
46
|
-
"residual-risks",
|
|
47
|
-
"no-staged-files",
|
|
48
|
-
"diff-summary",
|
|
49
|
-
"review-findings",
|
|
50
|
-
"manual-notes",
|
|
51
|
-
];
|
|
52
|
-
const VALID_EVIDENCE = new Set<AcceptanceEvidenceKind>(VALID_EVIDENCE_KINDS);
|
|
53
|
-
const ACCEPTANCE_EVIDENCE_HELP = `Supported evidence kinds: ${VALID_EVIDENCE_KINDS.join(", ")}. Example: { level: "checked", evidence: ["commands-run", "changed-files"] }.`;
|
|
54
|
-
const ACCEPTANCE_OBJECT_EXAMPLE = "Example: { level: \"checked\", evidence: [\"commands-run\", \"changed-files\"] }.";
|
|
55
|
-
const ACCEPTANCE_CONFIG_KEYS = new Set(["level", "report", "preserveStagedIndex", "criteria", "evidence", "verify", "review", "stopRules", "reason"]);
|
|
56
|
-
const ACCEPTANCE_GATE_KEYS = new Set(["id", "must", "evidence", "severity"]);
|
|
57
|
-
const ACCEPTANCE_VERIFY_KEYS = new Set(["id", "command", "timeoutMs", "cwd", "env", "allowFailure", "output", "schema"]);
|
|
58
|
-
const ACCEPTANCE_REVIEW_KEYS = new Set(["agent", "focus", "required"]);
|
|
59
|
-
const EXPLICIT_REVIEWED_UNAVAILABLE = "is an achieved status, not a requestable acceptance level. For a read-only reviewer call, omit acceptance. To require independent review of a writer result, use acceptance.review.required and orchestrate the reviewer separately.";
|
|
60
|
-
|
|
61
|
-
function normalizeLevel(level: AcceptanceLevel | undefined): Exclude<AcceptanceLevel, "auto"> | "auto" {
|
|
62
|
-
return level ?? "auto";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function unique<T>(items: T[]): T[] {
|
|
66
|
-
return [...new Set(items)];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function requiredEvidenceForLevel(level: Exclude<AcceptanceLevel, "auto">): AcceptanceEvidenceKind[] {
|
|
70
|
-
switch (level) {
|
|
71
|
-
case "none":
|
|
72
|
-
return [];
|
|
73
|
-
case "attested":
|
|
74
|
-
return ["manual-notes", "residual-risks"];
|
|
75
|
-
case "checked":
|
|
76
|
-
return ["changed-files", "tests-added", "commands-run", "residual-risks", "no-staged-files"];
|
|
77
|
-
case "verified":
|
|
78
|
-
return ["changed-files", "tests-added", "commands-run", "validation-output", "residual-risks", "no-staged-files"];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function inferLevel(input: {
|
|
83
|
-
agentName: string;
|
|
84
|
-
acceptanceRole?: AcceptanceRole;
|
|
85
|
-
task?: string;
|
|
86
|
-
mode?: SubagentRunMode;
|
|
87
|
-
async?: boolean;
|
|
88
|
-
dynamic?: boolean;
|
|
89
|
-
dynamicGroup?: boolean;
|
|
90
|
-
}): { level: Exclude<AcceptanceLevel, "auto">; reasons: string[]; criteria: string[]; evidence: AcceptanceEvidenceKind[]; review?: { agent?: string; required?: boolean } } {
|
|
91
|
-
const agent = input.agentName.toLowerCase();
|
|
92
|
-
const task = input.task?.toLowerCase() ?? "";
|
|
93
|
-
const reasons: string[] = [];
|
|
94
|
-
// Declared roles replace name heuristics, so use the full writer grammar to detect explicit mutation independently of the actual agent name.
|
|
95
|
-
const intent = classifyTaskMutationIntent(input.acceptanceRole ? "worker" : input.agentName, input.task ?? "");
|
|
96
|
-
const readOnlyTask = intent.kind === "read-only"
|
|
97
|
-
|| (intent.kind === "unknown" && /\b(?:read[- ]only|review[- ]only|no edits|without edits|inspect|summari[sz]e)\b/.test(task));
|
|
98
|
-
const rolePatchTask = input.acceptanceRole !== undefined
|
|
99
|
-
&& intent.kind !== "read-only"
|
|
100
|
-
&& !/\b(?:do not|don't|must not)\s+patch\b/.test(task)
|
|
101
|
-
&& /\bpatch\s+(?:(?:\.{0,2}[\\/])?(?:[\w.-]+[\\/])+[\w.-]+|[\w.-]+\.[a-z0-9]+\b|(?:the\s+)?parser\b)/.test(stripSeverityCompounds(task));
|
|
102
|
-
const taskMayWrite = readOnlyTask ? false : taskMayMutate(input.task ?? "") || intent.kind === "implementation" || rolePatchTask;
|
|
103
|
-
const readOnlyAgent = input.acceptanceRole === "read-only"
|
|
104
|
-
|| (input.acceptanceRole === undefined && /\b(?:reviewer|oracle|scout|researcher|analyst)\b/.test(agent));
|
|
105
|
-
const writeTask = taskMayWrite
|
|
106
|
-
|| (input.acceptanceRole === "writer" && !readOnlyTask)
|
|
107
|
-
|| (input.acceptanceRole === undefined && /\bworker\b/.test(agent) && !readOnlyTask);
|
|
108
|
-
const inferredReadOnly = readOnlyTask || ((readOnlyAgent || input.acceptanceRole === "read-only") && !taskMayWrite);
|
|
109
|
-
const roleResolvesReadOnly = input.acceptanceRole !== undefined && inferredReadOnly;
|
|
110
|
-
const dynamicResolvesReadOnly = inferredReadOnly && !writeTask;
|
|
111
|
-
const riskyKeywordPattern = /\b(?:release|migration|migrate|security|data[- ]loss|destructive|post-review|fix pass)\b/;
|
|
112
|
-
// Topic keywords cannot override classified read-only intent; unknown tasks keep their risk gate.
|
|
113
|
-
const keywordRiskReadOnly = input.acceptanceRole === undefined
|
|
114
|
-
? intent.kind === "read-only"
|
|
115
|
-
: inferredReadOnly;
|
|
116
|
-
const risky = Boolean(input.async && writeTask)
|
|
117
|
-
|| (Boolean(input.dynamic) && !roleResolvesReadOnly && !dynamicResolvesReadOnly)
|
|
118
|
-
|| (Boolean(input.dynamicGroup) && !roleResolvesReadOnly && !dynamicResolvesReadOnly)
|
|
119
|
-
|| (!keywordRiskReadOnly && riskyKeywordPattern.test(task));
|
|
120
|
-
|
|
121
|
-
if (risky) {
|
|
122
|
-
reasons.push(input.async ? "async write-capable or risky run" : "risky write-capable run");
|
|
123
|
-
if (input.dynamic || input.dynamicGroup) reasons.push("dynamic fanout context");
|
|
124
|
-
return {
|
|
125
|
-
level: "checked",
|
|
126
|
-
reasons,
|
|
127
|
-
criteria: ["Implement the requested change without widening scope", "Return evidence sufficient for an independent acceptance review"],
|
|
128
|
-
evidence: requiredEvidenceForLevel("checked"),
|
|
129
|
-
review: { agent: "reviewer", required: true },
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
if (writeTask && !readOnlyTask) {
|
|
133
|
-
reasons.push(input.acceptanceRole === "writer" && !taskMayWrite ? "declared writer acceptance role" : "write-capable worker/task");
|
|
134
|
-
return {
|
|
135
|
-
level: "checked",
|
|
136
|
-
reasons,
|
|
137
|
-
criteria: ["Implement the requested change without widening scope"],
|
|
138
|
-
evidence: requiredEvidenceForLevel("checked"),
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (readOnlyAgent || readOnlyTask) {
|
|
142
|
-
reasons.push(input.acceptanceRole === "read-only" && !readOnlyTask ? "declared read-only acceptance role" : readOnlyAgent ? "read-only/reviewer-style agent" : "read-only task wording");
|
|
143
|
-
return {
|
|
144
|
-
level: "none",
|
|
145
|
-
reasons,
|
|
146
|
-
criteria: ["Return concrete findings with file paths and severity when applicable"],
|
|
147
|
-
evidence: ["review-findings", "residual-risks"],
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
reasons.push("default lightweight attestation");
|
|
151
|
-
return {
|
|
152
|
-
level: "attested",
|
|
153
|
-
reasons,
|
|
154
|
-
criteria: ["Return a concise result and residual risks when applicable"],
|
|
155
|
-
evidence: ["manual-notes", "residual-risks"],
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
type AcceptanceInputNormalizationResult = { value: unknown; error?: string };
|
|
160
|
-
|
|
161
|
-
function normalizeAcceptanceValue(input: unknown, pathLabel = "acceptance"): AcceptanceInputNormalizationResult {
|
|
162
|
-
if (typeof input !== "string") return { value: input };
|
|
163
|
-
const trimmed = input.trim();
|
|
164
|
-
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return { value: input };
|
|
165
|
-
let parsed: unknown;
|
|
166
|
-
try {
|
|
167
|
-
parsed = JSON.parse(trimmed);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
return {
|
|
170
|
-
value: input,
|
|
171
|
-
error: `${pathLabel} JSON string must encode a valid acceptance object: ${error instanceof Error ? error.message : String(error)}`,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
175
|
-
const kind = parsed === null ? "null" : Array.isArray(parsed) ? "an array" : typeof parsed;
|
|
176
|
-
return { value: input, error: `${pathLabel} JSON string must encode an object; got ${kind}.` };
|
|
177
|
-
}
|
|
178
|
-
return { value: parsed };
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function normalizeAcceptanceInput(input: unknown): AcceptanceConfig {
|
|
182
|
-
const normalized = normalizeAcceptanceValue(input);
|
|
183
|
-
if (normalized.error) throw new Error(normalized.error);
|
|
184
|
-
input = normalized.value;
|
|
185
|
-
if (input === undefined || input === "auto") return { level: "auto" };
|
|
186
|
-
if (input === false) return { level: "none", reason: "disabled by deprecated false shorthand" };
|
|
187
|
-
if (typeof input === "string") return { level: input as AcceptanceConfig["level"] };
|
|
188
|
-
return { ...(input as AcceptanceConfig) };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export type ResolvedAcceptanceReportMode = "off" | "optional" | "required";
|
|
192
|
-
|
|
193
|
-
export function resolveAcceptanceReportMode(input: unknown): ResolvedAcceptanceReportMode {
|
|
194
|
-
const normalized = normalizeAcceptanceValue(input);
|
|
195
|
-
if (normalized.error) throw new Error(normalized.error);
|
|
196
|
-
const value = normalized.value;
|
|
197
|
-
const report = value && typeof value === "object" && !Array.isArray(value) ? (value as AcceptanceConfig).report : undefined;
|
|
198
|
-
return value === false || report === "off" ? "off" : report === "on" ? "required" : "optional";
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
type GateAcceptanceNormalizationResult =
|
|
202
|
-
| { ok: true; acceptance?: AcceptanceInput }
|
|
203
|
-
| { ok: false; error: string };
|
|
204
|
-
|
|
205
|
-
const GATE_OBJECT_KEYS = new Set(["command", "output", "schema", "timeoutMs"]);
|
|
206
|
-
export const GATE_INPUT_ERROR = "gate must be a non-empty command string or { command, output?: \"json\", schema?, timeoutMs? }.";
|
|
207
|
-
|
|
208
|
-
export interface GateObjectInput {
|
|
209
|
-
command: string;
|
|
210
|
-
output?: "json";
|
|
211
|
-
schema?: JsonSchemaObject;
|
|
212
|
-
timeoutMs?: number;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/** Validates the two accepted gate shapes without normalizing them. Shared by preflight and the workflow sandbox mirror. */
|
|
216
|
-
export function parseGateInput(gate: unknown): { ok: true; gate: GateObjectInput } | { ok: false; error: string } {
|
|
217
|
-
if (typeof gate === "string") {
|
|
218
|
-
return gate.trim() ? { ok: true, gate: { command: gate.trim() } } : { ok: false, error: GATE_INPUT_ERROR };
|
|
219
|
-
}
|
|
220
|
-
if (!gate || typeof gate !== "object" || Array.isArray(gate)) return { ok: false, error: GATE_INPUT_ERROR };
|
|
221
|
-
const value = gate as Record<string, unknown>;
|
|
222
|
-
for (const key of Object.keys(value)) {
|
|
223
|
-
if (!GATE_OBJECT_KEYS.has(key)) return { ok: false, error: `gate.${key} is not supported.` };
|
|
224
|
-
}
|
|
225
|
-
if (typeof value.command !== "string" || !value.command.trim()) return { ok: false, error: GATE_INPUT_ERROR };
|
|
226
|
-
if (value.output !== undefined && value.output !== "json") return { ok: false, error: "gate.output must be \"json\" when present." };
|
|
227
|
-
if (value.schema !== undefined) {
|
|
228
|
-
if (value.output !== "json") return { ok: false, error: "gate.schema requires gate.output: \"json\"." };
|
|
229
|
-
if (!value.schema || typeof value.schema !== "object" || Array.isArray(value.schema)) return { ok: false, error: "gate.schema must be a JSON Schema object." };
|
|
230
|
-
}
|
|
231
|
-
if (value.timeoutMs !== undefined && (!Number.isInteger(value.timeoutMs) || (value.timeoutMs as number) < 1)) return { ok: false, error: "gate.timeoutMs must be an integer >= 1." };
|
|
232
|
-
const parsed: GateObjectInput = { command: value.command.trim() };
|
|
233
|
-
if (value.output === "json") parsed.output = "json";
|
|
234
|
-
// SAFETY: schema was checked above to be a non-array object; timeoutMs to be an integer >= 1.
|
|
235
|
-
if (value.schema !== undefined) parsed.schema = value.schema as JsonSchemaObject;
|
|
236
|
-
if (value.timeoutMs !== undefined) parsed.timeoutMs = value.timeoutMs as number;
|
|
237
|
-
return { ok: true, gate: parsed };
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/** True when an acceptance policy declares at least one `output: "json"` verify command, from either the gate shorthand or an explicit verify list. */
|
|
241
|
-
export function acceptanceHasTypedVerify(acceptance: AcceptanceInput | undefined): boolean {
|
|
242
|
-
if (!acceptance || typeof acceptance !== "object") return false;
|
|
243
|
-
return Array.isArray(acceptance.verify) && acceptance.verify.some((command) => command && typeof command === "object" && command.output === "json");
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const TYPED_VERIFY_OUTPUT_SCHEMA_CONFLICT = "a typed verify command (output: \"json\") cannot be combined with outputSchema; the child would have two structured-output sources.";
|
|
247
|
-
|
|
248
|
-
export function normalizeGateAcceptance(gate: unknown, acceptance: AcceptanceInput | undefined): GateAcceptanceNormalizationResult {
|
|
249
|
-
if (gate === undefined) {
|
|
250
|
-
if (acceptance === undefined) return { ok: true };
|
|
251
|
-
const normalized = normalizeAcceptanceValue(acceptance);
|
|
252
|
-
return normalized.error ? { ok: false, error: normalized.error } : { ok: true, acceptance: normalized.value as AcceptanceInput };
|
|
253
|
-
}
|
|
254
|
-
const parsed = parseGateInput(gate);
|
|
255
|
-
if (!parsed.ok) return { ok: false, error: parsed.error };
|
|
256
|
-
if (acceptance !== undefined && acceptance !== false) return { ok: false, error: "gate cannot be combined with acceptance; use one gate command or acceptance.verify." + describeGateAcceptanceConflict(gate, acceptance) };
|
|
257
|
-
return { ok: true, acceptance: { level: "verified", verify: [{ id: "gate", ...parsed.gate }] } };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
export function describeGateAcceptanceConflict(gate: unknown, acceptance: unknown): string {
|
|
261
|
-
const render = (value: unknown): string => {
|
|
262
|
-
let encoded: string;
|
|
263
|
-
try {
|
|
264
|
-
encoded = JSON.stringify(value) ?? String(value);
|
|
265
|
-
} catch {
|
|
266
|
-
encoded = String(value);
|
|
267
|
-
}
|
|
268
|
-
return encoded.length > 120 ? `${encoded.slice(0, 120)}...` : encoded;
|
|
269
|
-
};
|
|
270
|
-
return ` Both fields were present: gate=${render(gate)} acceptance=${render(acceptance)}.`;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function explicitAcceptanceCanDisable(explicit: AcceptanceConfig): boolean {
|
|
274
|
-
return explicit.level === "none" && typeof explicit.reason === "string" && explicit.reason.trim().length > 0;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function explicitAcceptanceRequestsPolicy(explicit: AcceptanceConfig): boolean {
|
|
278
|
-
return (explicit.level !== undefined && explicit.level !== "auto") || Object.keys(explicit).some((key) => key !== "level");
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
function unsupportedEvidenceKindMessage(pathLabel: string, item: unknown): string {
|
|
282
|
-
const value = typeof item === "string" ? ` "${item}"` : "";
|
|
283
|
-
return `${pathLabel}${value} is not a supported evidence kind. ${ACCEPTANCE_EVIDENCE_HELP}`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export function validateAcceptanceInput(input: unknown, pathLabel = "acceptance"): string[] {
|
|
287
|
-
const errors: string[] = [];
|
|
288
|
-
if (input === undefined) return errors;
|
|
289
|
-
if (input === false) return errors;
|
|
290
|
-
const normalized = normalizeAcceptanceValue(input, pathLabel);
|
|
291
|
-
if (normalized.error) return [normalized.error];
|
|
292
|
-
input = normalized.value;
|
|
293
|
-
if (typeof input === "string") {
|
|
294
|
-
if (input === "reviewed") errors.push(`${pathLabel} ${EXPLICIT_REVIEWED_UNAVAILABLE}`);
|
|
295
|
-
else if (!VALID_LEVELS.has(input as AcceptanceLevel)) errors.push(`${pathLabel} has invalid level '${input}'.`);
|
|
296
|
-
else if (input === "none") errors.push(`${pathLabel} level "none" requires a reason; use { level: "none", reason: "..." }.`);
|
|
297
|
-
else if (input === "verified") errors.push(`${pathLabel} level "verified" requires object form with at least one runtime verify command. Use level "checked" or provide a non-empty acceptance.verify array.`);
|
|
298
|
-
return errors;
|
|
299
|
-
}
|
|
300
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
301
|
-
errors.push(`${pathLabel} must be a string level, false, or an object. ${ACCEPTANCE_OBJECT_EXAMPLE}`);
|
|
302
|
-
return errors;
|
|
303
|
-
}
|
|
304
|
-
const value = input as Record<string, unknown>;
|
|
305
|
-
for (const key of Object.keys(value)) {
|
|
306
|
-
if (!ACCEPTANCE_CONFIG_KEYS.has(key)) errors.push(`${pathLabel}.${key} is not supported.`);
|
|
307
|
-
}
|
|
308
|
-
if (value.level === "reviewed") {
|
|
309
|
-
errors.push(`${pathLabel}.level ${EXPLICIT_REVIEWED_UNAVAILABLE}`);
|
|
310
|
-
} else if (value.level !== undefined && (typeof value.level !== "string" || !VALID_LEVELS.has(value.level as AcceptanceLevel))) {
|
|
311
|
-
errors.push(`${pathLabel}.level must be one of auto, none, attested, checked, verified.`);
|
|
312
|
-
}
|
|
313
|
-
if (value.report !== undefined && value.report !== "on" && value.report !== "off") {
|
|
314
|
-
errors.push(`${pathLabel}.report must be on or off.`);
|
|
315
|
-
}
|
|
316
|
-
if (value.preserveStagedIndex !== undefined && value.preserveStagedIndex !== true) {
|
|
317
|
-
errors.push(`${pathLabel}.preserveStagedIndex must be true when provided.`);
|
|
318
|
-
}
|
|
319
|
-
if (value.preserveStagedIndex === true && value.level !== "checked" && value.level !== "verified") {
|
|
320
|
-
errors.push(`${pathLabel}.preserveStagedIndex requires level checked or verified.`);
|
|
321
|
-
}
|
|
322
|
-
if (value.level === "none" && (typeof value.reason !== "string" || !value.reason.trim())) {
|
|
323
|
-
errors.push(`${pathLabel}.reason is required when level is none.`);
|
|
324
|
-
}
|
|
325
|
-
if (value.reason !== undefined && typeof value.reason !== "string") errors.push(`${pathLabel}.reason must be a string.`);
|
|
326
|
-
if (value.criteria !== undefined && !Array.isArray(value.criteria)) errors.push(`${pathLabel}.criteria must be an array.`);
|
|
327
|
-
if (Array.isArray(value.criteria)) {
|
|
328
|
-
const criterionIds = new Set<string>();
|
|
329
|
-
for (const [index, criterion] of value.criteria.entries()) {
|
|
330
|
-
if (typeof criterion === "string") continue;
|
|
331
|
-
const criterionPath = `${pathLabel}.criteria[${index}]`;
|
|
332
|
-
if (!criterion || typeof criterion !== "object" || Array.isArray(criterion)) {
|
|
333
|
-
errors.push(`${criterionPath} must be a string or an object.`);
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
const gate = criterion as Record<string, unknown>;
|
|
337
|
-
for (const key of Object.keys(gate)) {
|
|
338
|
-
if (!ACCEPTANCE_GATE_KEYS.has(key)) errors.push(`${criterionPath}.${key} is not supported.`);
|
|
339
|
-
}
|
|
340
|
-
if (typeof gate.id !== "string" || !gate.id.trim()) {
|
|
341
|
-
errors.push(`${criterionPath}.id is required.`);
|
|
342
|
-
} else {
|
|
343
|
-
const normalizedId = normalizedToken(gate.id);
|
|
344
|
-
if (criterionIds.has(normalizedId)) errors.push(`${criterionPath}.id duplicates normalized criterion id '${normalizedId}'.`);
|
|
345
|
-
criterionIds.add(normalizedId);
|
|
346
|
-
}
|
|
347
|
-
if (typeof gate.must !== "string" || !gate.must.trim()) errors.push(`${criterionPath}.must is required.`);
|
|
348
|
-
if (gate.evidence !== undefined && !Array.isArray(gate.evidence)) errors.push(`${criterionPath}.evidence must be an array. ${ACCEPTANCE_EVIDENCE_HELP}`);
|
|
349
|
-
if (Array.isArray(gate.evidence)) {
|
|
350
|
-
for (const [evidenceIndex, item] of gate.evidence.entries()) {
|
|
351
|
-
if (typeof item !== "string" || !VALID_EVIDENCE.has(item as AcceptanceEvidenceKind)) {
|
|
352
|
-
errors.push(unsupportedEvidenceKindMessage(`${criterionPath}.evidence[${evidenceIndex}]`, item));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
if (gate.severity !== undefined && gate.severity !== "required" && gate.severity !== "recommended") {
|
|
357
|
-
errors.push(`${criterionPath}.severity must be required or recommended.`);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (Array.isArray(value.evidence)) {
|
|
362
|
-
for (const [index, item] of value.evidence.entries()) {
|
|
363
|
-
if (typeof item !== "string" || !VALID_EVIDENCE.has(item as AcceptanceEvidenceKind)) {
|
|
364
|
-
errors.push(unsupportedEvidenceKindMessage(`${pathLabel}.evidence[${index}]`, item));
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
} else if (value.evidence !== undefined) {
|
|
368
|
-
errors.push(`${pathLabel}.evidence must be an array. ${ACCEPTANCE_EVIDENCE_HELP}`);
|
|
369
|
-
}
|
|
370
|
-
if (value.level === "verified" && (!Array.isArray(value.verify) || value.verify.length === 0)) {
|
|
371
|
-
errors.push(`${pathLabel}.verify must contain at least one runtime command when level is verified. Use level "checked" or provide a non-empty acceptance.verify array.`);
|
|
372
|
-
} else if (value.verify !== undefined && !Array.isArray(value.verify)) {
|
|
373
|
-
errors.push(`${pathLabel}.verify must be an array.`);
|
|
374
|
-
}
|
|
375
|
-
if (Array.isArray(value.verify)) {
|
|
376
|
-
for (const [index, command] of value.verify.entries()) {
|
|
377
|
-
if (!command || typeof command !== "object" || Array.isArray(command)) {
|
|
378
|
-
errors.push(`${pathLabel}.verify[${index}] must be an object.`);
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
const cmd = command as Record<string, unknown>;
|
|
382
|
-
for (const key of Object.keys(cmd)) {
|
|
383
|
-
if (!ACCEPTANCE_VERIFY_KEYS.has(key)) errors.push(`${pathLabel}.verify[${index}].${key} is not supported.`);
|
|
384
|
-
}
|
|
385
|
-
if (typeof cmd.id !== "string" || !cmd.id.trim()) errors.push(`${pathLabel}.verify[${index}].id is required.`);
|
|
386
|
-
if (typeof cmd.command !== "string" || !cmd.command.trim()) errors.push(`${pathLabel}.verify[${index}].command is required.`);
|
|
387
|
-
if (cmd.timeoutMs !== undefined && (typeof cmd.timeoutMs !== "number" || !Number.isInteger(cmd.timeoutMs) || cmd.timeoutMs < 1)) {
|
|
388
|
-
errors.push(`${pathLabel}.verify[${index}].timeoutMs must be an integer >= 1.`);
|
|
389
|
-
}
|
|
390
|
-
if (cmd.cwd !== undefined && typeof cmd.cwd !== "string") errors.push(`${pathLabel}.verify[${index}].cwd must be a string.`);
|
|
391
|
-
if (cmd.env !== undefined) {
|
|
392
|
-
if (!cmd.env || typeof cmd.env !== "object" || Array.isArray(cmd.env)) {
|
|
393
|
-
errors.push(`${pathLabel}.verify[${index}].env must be an object.`);
|
|
394
|
-
} else {
|
|
395
|
-
for (const [envKey, envValue] of Object.entries(cmd.env as Record<string, unknown>)) {
|
|
396
|
-
if (typeof envValue !== "string") errors.push(`${pathLabel}.verify[${index}].env.${envKey} must be a string.`);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
if (cmd.allowFailure !== undefined && typeof cmd.allowFailure !== "boolean") {
|
|
401
|
-
errors.push(`${pathLabel}.verify[${index}].allowFailure must be a boolean.`);
|
|
402
|
-
}
|
|
403
|
-
if (cmd.output !== undefined && cmd.output !== "json") errors.push(`${pathLabel}.verify[${index}].output must be "json" when present.`);
|
|
404
|
-
if (cmd.schema !== undefined) {
|
|
405
|
-
if (cmd.output !== "json") errors.push(`${pathLabel}.verify[${index}].schema requires output: "json".`);
|
|
406
|
-
if (!cmd.schema || typeof cmd.schema !== "object" || Array.isArray(cmd.schema)) errors.push(`${pathLabel}.verify[${index}].schema must be a JSON Schema object.`);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
if (value.review !== undefined && value.review !== false) {
|
|
411
|
-
if (!value.review || typeof value.review !== "object" || Array.isArray(value.review)) {
|
|
412
|
-
errors.push(`${pathLabel}.review must be false or an object.`);
|
|
413
|
-
} else {
|
|
414
|
-
const review = value.review as Record<string, unknown>;
|
|
415
|
-
for (const key of Object.keys(review)) {
|
|
416
|
-
if (!ACCEPTANCE_REVIEW_KEYS.has(key)) errors.push(`${pathLabel}.review.${key} is not supported.`);
|
|
417
|
-
}
|
|
418
|
-
if (review.agent !== undefined && typeof review.agent !== "string") errors.push(`${pathLabel}.review.agent must be a string.`);
|
|
419
|
-
if (review.focus !== undefined && typeof review.focus !== "string") errors.push(`${pathLabel}.review.focus must be a string.`);
|
|
420
|
-
if (review.required !== undefined && typeof review.required !== "boolean") errors.push(`${pathLabel}.review.required must be a boolean.`);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
if (value.stopRules !== undefined && !Array.isArray(value.stopRules)) errors.push(`${pathLabel}.stopRules must be an array.`);
|
|
424
|
-
if (Array.isArray(value.stopRules)) {
|
|
425
|
-
for (const [index, item] of value.stopRules.entries()) {
|
|
426
|
-
if (typeof item !== "string") errors.push(`${pathLabel}.stopRules[${index}] must be a string.`);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
return errors;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
type ExecutionAcceptanceInput = {
|
|
433
|
-
acceptance?: unknown;
|
|
434
|
-
outputSchema?: unknown;
|
|
435
|
-
tasks?: Array<{ acceptance?: unknown; outputSchema?: unknown }>;
|
|
436
|
-
chain?: Array<{
|
|
437
|
-
acceptance?: unknown;
|
|
438
|
-
outputSchema?: unknown;
|
|
439
|
-
parallel?: Array<{ acceptance?: unknown; outputSchema?: unknown }> | { acceptance?: unknown; outputSchema?: unknown };
|
|
440
|
-
}>;
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
export function validateExecutionAcceptancePolicy(input: ExecutionAcceptanceInput): string[] {
|
|
444
|
-
const errors = validateAcceptanceInput(input.acceptance, "acceptance");
|
|
445
|
-
for (const [index, task] of (input.tasks ?? []).entries()) {
|
|
446
|
-
errors.push(...validateAcceptanceInput(task.acceptance, `tasks[${index}].acceptance`));
|
|
447
|
-
}
|
|
448
|
-
for (const [stepIndex, step] of (input.chain ?? []).entries()) {
|
|
449
|
-
errors.push(...validateAcceptanceInput(step.acceptance, `chain[${stepIndex}].acceptance`));
|
|
450
|
-
if (Array.isArray(step.parallel)) {
|
|
451
|
-
for (const [taskIndex, task] of step.parallel.entries()) {
|
|
452
|
-
errors.push(...validateAcceptanceInput(task.acceptance, `chain[${stepIndex}].parallel[${taskIndex}].acceptance`));
|
|
453
|
-
}
|
|
454
|
-
} else if (step.parallel) {
|
|
455
|
-
errors.push(...validateAcceptanceInput(step.parallel.acceptance, `chain[${stepIndex}].parallel.acceptance`));
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
return errors;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
export function validateExecutionAcceptance(input: ExecutionAcceptanceInput): string[] {
|
|
462
|
-
const errors = validateExecutionAcceptancePolicy(input);
|
|
463
|
-
errors.push(...validateAcceptanceReportMode(input.acceptance, input.outputSchema, "acceptance"));
|
|
464
|
-
for (const [index, task] of (input.tasks ?? []).entries()) {
|
|
465
|
-
errors.push(...validateAcceptanceReportMode(task.acceptance, task.outputSchema, `tasks[${index}].acceptance`));
|
|
466
|
-
}
|
|
467
|
-
for (const [stepIndex, step] of (input.chain ?? []).entries()) {
|
|
468
|
-
errors.push(...validateAcceptanceReportMode(step.acceptance, step.outputSchema, `chain[${stepIndex}].acceptance`));
|
|
469
|
-
if (Array.isArray(step.parallel)) {
|
|
470
|
-
for (const [taskIndex, task] of step.parallel.entries()) {
|
|
471
|
-
errors.push(...validateAcceptanceReportMode(task.acceptance, task.outputSchema, `chain[${stepIndex}].parallel[${taskIndex}].acceptance`));
|
|
472
|
-
}
|
|
473
|
-
} else if (step.parallel) {
|
|
474
|
-
errors.push(...validateAcceptanceReportMode(step.parallel.acceptance, step.parallel.outputSchema, `chain[${stepIndex}].parallel.acceptance`));
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
return errors;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
function validateAcceptanceReportMode(acceptance: unknown, outputSchema: unknown, pathLabel: string): string[] {
|
|
481
|
-
const normalized = normalizeAcceptanceValue(acceptance, pathLabel);
|
|
482
|
-
if (normalized.error) return [];
|
|
483
|
-
acceptance = normalized.value;
|
|
484
|
-
if (!acceptance || typeof acceptance !== "object" || Array.isArray(acceptance)) return [];
|
|
485
|
-
if (!("report" in acceptance)) return [];
|
|
486
|
-
return outputSchema === undefined || outputSchema === false ? [`${pathLabel}.report requires outputSchema.`] : [];
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
function normalizeCriteria(criteria: Array<string | { id?: string; must?: string; evidence?: AcceptanceEvidenceKind[]; severity?: "required" | "recommended" }> | undefined, evidence: AcceptanceEvidenceKind[]): ResolvedAcceptanceGate[] {
|
|
490
|
-
return (criteria ?? []).map((criterion, index): ResolvedAcceptanceGate => {
|
|
491
|
-
if (typeof criterion === "string") {
|
|
492
|
-
return { id: `criterion-${index + 1}`, must: criterion, evidence, severity: "required" };
|
|
493
|
-
}
|
|
494
|
-
return {
|
|
495
|
-
id: criterion.id?.trim() || `criterion-${index + 1}`,
|
|
496
|
-
must: criterion.must ?? "",
|
|
497
|
-
evidence: criterion.evidence?.filter((item) => VALID_EVIDENCE.has(item)) ?? evidence,
|
|
498
|
-
severity: criterion.severity ?? "required",
|
|
499
|
-
};
|
|
500
|
-
}).filter((criterion) => criterion.must.trim());
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export function resolveEffectiveAcceptance(input: {
|
|
504
|
-
explicit?: AcceptanceInput;
|
|
505
|
-
agentName: string;
|
|
506
|
-
acceptanceRole?: AcceptanceRole;
|
|
507
|
-
task?: string;
|
|
508
|
-
mode?: SubagentRunMode;
|
|
509
|
-
async?: boolean;
|
|
510
|
-
dynamic?: boolean;
|
|
511
|
-
dynamicGroup?: boolean;
|
|
512
|
-
agentContract?: AgentContract;
|
|
513
|
-
}): ResolvedAcceptanceConfig {
|
|
514
|
-
const explicit = normalizeAcceptanceInput(input.explicit);
|
|
515
|
-
const explicitLevel = normalizeLevel(explicit.level);
|
|
516
|
-
if (isAgentContract(input.agentContract)) {
|
|
517
|
-
const level = explicitAcceptanceCanDisable(explicit) || explicitLevel === "auto"
|
|
518
|
-
? "none"
|
|
519
|
-
: explicitLevel;
|
|
520
|
-
const evidence = unique(explicit.evidence ?? []);
|
|
521
|
-
const criteria = normalizeCriteria(
|
|
522
|
-
explicit.criteria as Array<string | { id?: string; must?: string; evidence?: AcceptanceEvidenceKind[]; severity?: "required" | "recommended" }> | undefined,
|
|
523
|
-
evidence,
|
|
524
|
-
);
|
|
525
|
-
return {
|
|
526
|
-
level,
|
|
527
|
-
explicit: input.explicit !== undefined,
|
|
528
|
-
inferredReason: [],
|
|
529
|
-
criteria,
|
|
530
|
-
evidence,
|
|
531
|
-
preserveStagedIndex: explicit.preserveStagedIndex,
|
|
532
|
-
verify: explicit.verify ?? [],
|
|
533
|
-
review: explicit.review,
|
|
534
|
-
stopRules: explicit.stopRules ?? [],
|
|
535
|
-
reason: explicit.reason,
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
const inferred = inferLevel(input);
|
|
539
|
-
const inferredLevel = inferred.level === "none" && explicitAcceptanceRequestsPolicy(explicit) ? "attested" : inferred.level;
|
|
540
|
-
const level = explicitAcceptanceCanDisable(explicit)
|
|
541
|
-
? "none"
|
|
542
|
-
: explicitLevel === "auto"
|
|
543
|
-
? inferredLevel
|
|
544
|
-
: (LEVEL_RANK[explicitLevel] >= LEVEL_RANK[inferredLevel] ? explicitLevel : inferredLevel);
|
|
545
|
-
const evidence = unique([...(level === inferredLevel ? inferred.evidence : requiredEvidenceForLevel(level)), ...(explicit.evidence ?? [])]);
|
|
546
|
-
const criteria = normalizeCriteria(
|
|
547
|
-
(explicit.criteria?.length ? explicit.criteria : inferred.criteria) as Array<string | { id?: string; must?: string; evidence?: AcceptanceEvidenceKind[]; severity?: "required" | "recommended" }>,
|
|
548
|
-
evidence,
|
|
549
|
-
);
|
|
550
|
-
const review = explicit.review !== undefined ? explicit.review : inferred.review;
|
|
551
|
-
return {
|
|
552
|
-
level,
|
|
553
|
-
explicit: input.explicit !== undefined,
|
|
554
|
-
inferredReason: inferred.reasons,
|
|
555
|
-
criteria: level === "none" ? [] : criteria,
|
|
556
|
-
evidence: level === "none" ? [] : evidence,
|
|
557
|
-
preserveStagedIndex: explicit.preserveStagedIndex,
|
|
558
|
-
verify: explicit.verify ?? [],
|
|
559
|
-
review,
|
|
560
|
-
stopRules: explicit.stopRules ?? [],
|
|
561
|
-
reason: explicit.reason,
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function acceptanceRequiresChildReport(acceptance: ResolvedAcceptanceConfig): boolean {
|
|
566
|
-
return acceptance.criteria.length > 0 || acceptance.evidence.length > 0;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/** Label a declared review gate the same way in prompts and capability summaries. */
|
|
570
|
-
export function formatReviewGateLabel(review: AcceptanceReviewGate): string {
|
|
571
|
-
const status = review.required === false ? "optional" : "required";
|
|
572
|
-
return review.agent ? `${status} by ${review.agent}` : status;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
export function formatAcceptancePrompt(acceptance: ResolvedAcceptanceConfig, options: { reportOptional?: boolean; structuredOutput?: boolean } = {}): string {
|
|
576
|
-
if (acceptance.level === "none") return "";
|
|
577
|
-
if (options.reportOptional && !acceptanceRequiresChildReport(acceptance)) return "";
|
|
578
|
-
const lines = [
|
|
579
|
-
"",
|
|
580
|
-
"## Acceptance Contract",
|
|
581
|
-
`Acceptance level: ${acceptance.level}`,
|
|
582
|
-
"Completion is not accepted from prose alone. End with a structured acceptance report.",
|
|
583
|
-
"",
|
|
584
|
-
"Criteria:",
|
|
585
|
-
...(acceptance.criteria.length ? acceptance.criteria.map((criterion) => `- ${criterion.id}: ${criterion.must}`) : ["- Return the requested result."]),
|
|
586
|
-
"",
|
|
587
|
-
`Required evidence: ${acceptance.evidence.join(", ") || "none"}`,
|
|
588
|
-
];
|
|
589
|
-
if (acceptance.preserveStagedIndex) {
|
|
590
|
-
lines.push("The host will verify that the staged index is unchanged from launch; report noStagedFiles truthfully even when the preserved index is non-empty.");
|
|
591
|
-
}
|
|
592
|
-
if (acceptance.verify.length > 0) {
|
|
593
|
-
lines.push("", "Runtime verification commands configured by parent:");
|
|
594
|
-
for (const command of acceptance.verify) lines.push(`- ${command.id}: ${command.command}`);
|
|
595
|
-
}
|
|
596
|
-
if (acceptance.review) {
|
|
597
|
-
lines.push("", `Review gate: ${formatReviewGateLabel(acceptance.review)}.`);
|
|
598
|
-
if (acceptance.review.focus) lines.push(`Review focus: ${acceptance.review.focus}`);
|
|
599
|
-
}
|
|
600
|
-
if (acceptance.stopRules.length > 0) {
|
|
601
|
-
lines.push("", "Stop rules:", ...acceptance.stopRules.map((rule) => `- ${rule}`));
|
|
602
|
-
}
|
|
603
|
-
lines.push(
|
|
604
|
-
"",
|
|
605
|
-
options.structuredOutput
|
|
606
|
-
? "Include an `acceptanceReport` object in your final `structured_output` tool call in this shape:"
|
|
607
|
-
: "Finish with a fenced JSON block tagged `acceptance-report` in this shape:",
|
|
608
|
-
"Use empty arrays when no items apply; array fields contain strings unless object entries are shown.",
|
|
609
|
-
"Empty-string entries (`[\"\"]`) are ignored; use `[]` when nothing applies.",
|
|
610
|
-
"`criteriaSatisfied[].status` must be exactly one of: satisfied, not-satisfied, not-applicable.",
|
|
611
|
-
"`commandsRun[].result` must be exactly one of: passed, failed, not-run.",
|
|
612
|
-
"`manualNotes` and `notes` are optional strings; an empty string means no note and does not satisfy `manual-notes` evidence.",
|
|
613
|
-
...(options.structuredOutput ? [] : ["```acceptance-report"]),
|
|
614
|
-
JSON.stringify({
|
|
615
|
-
criteriaSatisfied: acceptance.criteria
|
|
616
|
-
.filter((criterion) => criterion.severity !== "recommended")
|
|
617
|
-
.map((criterion) => ({ id: criterion.id, status: "satisfied", evidence: "specific proof" })),
|
|
618
|
-
changedFiles: ["src/file.ts"],
|
|
619
|
-
testsAddedOrUpdated: ["test/file.test.ts"],
|
|
620
|
-
commandsRun: [{ command: "command", result: "passed", summary: "short result" }],
|
|
621
|
-
validationOutput: ["validation output or concise summary"],
|
|
622
|
-
residualRisks: ["none"],
|
|
623
|
-
noStagedFiles: true,
|
|
624
|
-
diffSummary: "short description of the diff",
|
|
625
|
-
reviewFindings: ["blocker: file.ts:12 - issue found, or no blockers"],
|
|
626
|
-
manualNotes: "anything else the parent should know",
|
|
627
|
-
}, null, 2),
|
|
628
|
-
...(options.structuredOutput ? [] : ["```"]),
|
|
629
|
-
);
|
|
630
|
-
return lines.join("\n");
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
function extractBalancedJson(text: string, start: number): string | undefined {
|
|
634
|
-
let depth = 0;
|
|
635
|
-
let inString = false;
|
|
636
|
-
let escaped = false;
|
|
637
|
-
for (let i = start; i < text.length; i++) {
|
|
638
|
-
const char = text[i]!;
|
|
639
|
-
if (inString) {
|
|
640
|
-
if (escaped) escaped = false;
|
|
641
|
-
else if (char === "\\") escaped = true;
|
|
642
|
-
else if (char === "\"") inString = false;
|
|
643
|
-
continue;
|
|
644
|
-
}
|
|
645
|
-
if (char === "\"") {
|
|
646
|
-
inString = true;
|
|
647
|
-
continue;
|
|
648
|
-
}
|
|
649
|
-
if (char === "{") depth++;
|
|
650
|
-
if (char === "}") {
|
|
651
|
-
depth--;
|
|
652
|
-
if (depth === 0) return text.slice(start, i + 1);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
return undefined;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
const ACCEPTANCE_REPORT_WRAPPERS = new Set(["acceptance", "acceptance-report", "acceptance_report", "acceptanceReport"]);
|
|
659
|
-
|
|
660
|
-
const ACCEPTANCE_REPORT_FIELDS: Record<string, keyof AcceptanceReport> = {
|
|
661
|
-
criteriaSatisfied: "criteriaSatisfied",
|
|
662
|
-
criteria_satisfied: "criteriaSatisfied",
|
|
663
|
-
changedFiles: "changedFiles",
|
|
664
|
-
changed_files: "changedFiles",
|
|
665
|
-
testsAddedOrUpdated: "testsAddedOrUpdated",
|
|
666
|
-
tests_added_or_updated: "testsAddedOrUpdated",
|
|
667
|
-
commandsRun: "commandsRun",
|
|
668
|
-
commands_run: "commandsRun",
|
|
669
|
-
validationOutput: "validationOutput",
|
|
670
|
-
validation_output: "validationOutput",
|
|
671
|
-
residualRisks: "residualRisks",
|
|
672
|
-
residual_risks: "residualRisks",
|
|
673
|
-
noStagedFiles: "noStagedFiles",
|
|
674
|
-
no_staged_files: "noStagedFiles",
|
|
675
|
-
diffSummary: "diffSummary",
|
|
676
|
-
diff_summary: "diffSummary",
|
|
677
|
-
reviewFindings: "reviewFindings",
|
|
678
|
-
review_findings: "reviewFindings",
|
|
679
|
-
manualNotes: "manualNotes",
|
|
680
|
-
manual_notes: "manualNotes",
|
|
681
|
-
notes: "notes",
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
const CRITERION_REPORT_FIELDS = new Set(["id", "status", "evidence"]);
|
|
685
|
-
const COMMAND_REPORT_FIELDS = new Set(["command", "result", "summary"]);
|
|
686
|
-
|
|
687
|
-
function normalizedToken(value: string): string {
|
|
688
|
-
return value.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/-+/g, "-");
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
function normalizeCriterionStatus(value: unknown): unknown {
|
|
692
|
-
if (typeof value !== "string") return value;
|
|
693
|
-
const token = normalizedToken(value);
|
|
694
|
-
if (["satisfied", "met", "complete", "completed", "done", "pass", "passed", "success", "succeeded"].includes(token)) return "satisfied";
|
|
695
|
-
if (["not-satisfied", "not-met", "unmet", "incomplete", "fail", "failed"].includes(token)) return "not-satisfied";
|
|
696
|
-
if (["not-applicable", "n-a", "na", "skip", "skipped"].includes(token)) return "not-applicable";
|
|
697
|
-
return value;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
function normalizeCommandResult(value: unknown): unknown {
|
|
701
|
-
if (typeof value !== "string") return value;
|
|
702
|
-
const token = normalizedToken(value);
|
|
703
|
-
if (["passed", "pass", "success", "successful", "succeeded", "ok"].includes(token)) return "passed";
|
|
704
|
-
if (["failed", "fail", "failure", "error"].includes(token)) return "failed";
|
|
705
|
-
if (["not-run", "not-executed", "skip", "skipped"].includes(token)) return "not-run";
|
|
706
|
-
return value;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
function normalizeCriterionReport(value: unknown, pathLabel: string, errors: string[]): unknown {
|
|
710
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
711
|
-
const normalized: Record<string, unknown> = {};
|
|
712
|
-
for (const [key, fieldValue] of Object.entries(value as Record<string, unknown>)) {
|
|
713
|
-
if (!CRITERION_REPORT_FIELDS.has(key)) {
|
|
714
|
-
errors.push(`${pathLabel}.${key}: unsupported acceptance criterion field`);
|
|
715
|
-
continue;
|
|
716
|
-
}
|
|
717
|
-
normalized[key] = key === "id" && typeof fieldValue === "string"
|
|
718
|
-
? normalizedToken(fieldValue)
|
|
719
|
-
: key === "status"
|
|
720
|
-
? normalizeCriterionStatus(fieldValue)
|
|
721
|
-
: fieldValue;
|
|
722
|
-
}
|
|
723
|
-
return normalized;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
function normalizeCommandReport(value: unknown, pathLabel: string, errors: string[]): unknown {
|
|
727
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
728
|
-
const normalized: Record<string, unknown> = {};
|
|
729
|
-
for (const [key, fieldValue] of Object.entries(value as Record<string, unknown>)) {
|
|
730
|
-
if (!COMMAND_REPORT_FIELDS.has(key)) {
|
|
731
|
-
errors.push(`${pathLabel}.${key}: unsupported acceptance command field`);
|
|
732
|
-
continue;
|
|
733
|
-
}
|
|
734
|
-
normalized[key] = key === "result" ? normalizeCommandResult(fieldValue) : fieldValue;
|
|
735
|
-
}
|
|
736
|
-
return normalized;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
function normalizeAcceptanceReportValue(value: unknown, pathLabel = ""): { value: unknown; pathLabel: string; errors: string[] } {
|
|
740
|
-
const errors: string[] = [];
|
|
741
|
-
let reportValue = value;
|
|
742
|
-
let reportPath = pathLabel;
|
|
743
|
-
if (reportValue && typeof reportValue === "object" && !Array.isArray(reportValue)) {
|
|
744
|
-
const record = reportValue as Record<string, unknown>;
|
|
745
|
-
const wrapperKeys = Object.keys(record).filter((key) => ACCEPTANCE_REPORT_WRAPPERS.has(key));
|
|
746
|
-
if (wrapperKeys.length > 0) {
|
|
747
|
-
const wrapperKey = wrapperKeys[0]!;
|
|
748
|
-
if (wrapperKeys.length > 1) errors.push(`${pathLabel || "acceptance-report"}: multiple acceptance report wrappers are ambiguous`);
|
|
749
|
-
for (const key of Object.keys(record)) {
|
|
750
|
-
if (key !== wrapperKey) errors.push(`${pathFor(pathLabel, key)}: unsupported alongside acceptance report wrapper '${wrapperKey}'`);
|
|
751
|
-
}
|
|
752
|
-
reportValue = record[wrapperKey];
|
|
753
|
-
reportPath = pathFor(pathLabel, wrapperKey);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
if (!reportValue || typeof reportValue !== "object" || Array.isArray(reportValue)) return { value: reportValue, pathLabel: reportPath, errors };
|
|
757
|
-
|
|
758
|
-
const normalized: Record<string, unknown> = {};
|
|
759
|
-
for (const [key, fieldValue] of Object.entries(reportValue as Record<string, unknown>)) {
|
|
760
|
-
const canonical = ACCEPTANCE_REPORT_FIELDS[key];
|
|
761
|
-
if (!canonical) {
|
|
762
|
-
errors.push(`${pathFor(reportPath, key)}: unsupported acceptance report field`);
|
|
763
|
-
continue;
|
|
764
|
-
}
|
|
765
|
-
if (Object.hasOwn(normalized, canonical)) {
|
|
766
|
-
errors.push(`${pathFor(reportPath, key)}: duplicates normalized field '${canonical}'`);
|
|
767
|
-
continue;
|
|
768
|
-
}
|
|
769
|
-
const fieldPath = pathFor(reportPath, canonical);
|
|
770
|
-
switch (canonical) {
|
|
771
|
-
case "criteriaSatisfied": {
|
|
772
|
-
const items = Array.isArray(fieldValue) ? fieldValue : fieldValue && typeof fieldValue === "object" ? [fieldValue] : fieldValue;
|
|
773
|
-
normalized[canonical] = Array.isArray(items)
|
|
774
|
-
? items.map((item, index) => normalizeCriterionReport(item, `${fieldPath}[${index}]`, errors))
|
|
775
|
-
: items;
|
|
776
|
-
break;
|
|
777
|
-
}
|
|
778
|
-
case "commandsRun": {
|
|
779
|
-
const items = Array.isArray(fieldValue) ? fieldValue : fieldValue && typeof fieldValue === "object" ? [fieldValue] : fieldValue;
|
|
780
|
-
normalized[canonical] = Array.isArray(items)
|
|
781
|
-
? items.map((item, index) => normalizeCommandReport(item, `${fieldPath}[${index}]`, errors))
|
|
782
|
-
: items;
|
|
783
|
-
break;
|
|
784
|
-
}
|
|
785
|
-
case "changedFiles":
|
|
786
|
-
case "testsAddedOrUpdated":
|
|
787
|
-
case "validationOutput":
|
|
788
|
-
case "residualRisks":
|
|
789
|
-
case "reviewFindings": {
|
|
790
|
-
// Tolerate empty-string entries ("[\"\"]"): models write them for "no items"
|
|
791
|
-
// and a single empty entry must not reject the whole report. Drop them at
|
|
792
|
-
// parse time; non-string entries are kept so validateStringArrayField still
|
|
793
|
-
// flags structural garbage.
|
|
794
|
-
const items = typeof fieldValue === "string" ? [fieldValue] : fieldValue;
|
|
795
|
-
normalized[canonical] = Array.isArray(items)
|
|
796
|
-
? items.filter((item) => typeof item !== "string" || item.trim().length > 0)
|
|
797
|
-
: items;
|
|
798
|
-
break;
|
|
799
|
-
}
|
|
800
|
-
case "noStagedFiles": {
|
|
801
|
-
const token = typeof fieldValue === "string" ? fieldValue.trim().toLowerCase() : undefined;
|
|
802
|
-
normalized[canonical] = token === "true" ? true : token === "false" ? false : fieldValue;
|
|
803
|
-
break;
|
|
804
|
-
}
|
|
805
|
-
default:
|
|
806
|
-
normalized[canonical] = fieldValue;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
return { value: normalized, pathLabel: reportPath, errors };
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function hasGenericAcceptanceReportSignal(value: unknown): boolean {
|
|
813
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
814
|
-
const record = value as Record<string, unknown>;
|
|
815
|
-
return "criteriaSatisfied" in record && [
|
|
816
|
-
"changedFiles",
|
|
817
|
-
"testsAddedOrUpdated",
|
|
818
|
-
"commandsRun",
|
|
819
|
-
"validationOutput",
|
|
820
|
-
"residualRisks",
|
|
821
|
-
"noStagedFiles",
|
|
822
|
-
"diffSummary",
|
|
823
|
-
"reviewFindings",
|
|
824
|
-
"manualNotes",
|
|
825
|
-
].some((key) => key in record);
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
function parseReportJson(body: string): unknown {
|
|
829
|
-
const trimmed = body.trim();
|
|
830
|
-
try {
|
|
831
|
-
return JSON.parse(trimmed) as unknown;
|
|
832
|
-
} catch (error) {
|
|
833
|
-
const jsonStart = trimmed.indexOf("{");
|
|
834
|
-
if (jsonStart > 0) {
|
|
835
|
-
const json = extractBalancedJson(trimmed, jsonStart);
|
|
836
|
-
if (json) return JSON.parse(json) as unknown;
|
|
837
|
-
}
|
|
838
|
-
throw error;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
function fencedBlocks(output: string, tag: string): string[] {
|
|
843
|
-
return [...output.matchAll(new RegExp(`\`\`\`${tag}\\s*\\n([\\s\\S]*?)\`\`\``, "gi"))]
|
|
844
|
-
.map((match) => match[1]?.trim())
|
|
845
|
-
.filter((value): value is string => Boolean(value));
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
function parseAcceptanceReportBody(body: string): { report?: AcceptanceReport; errors: string[] } {
|
|
849
|
-
return validateAcceptanceReport(parseReportJson(body));
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
interface AcceptanceReportParseResult {
|
|
853
|
-
report?: AcceptanceReport;
|
|
854
|
-
error?: string;
|
|
855
|
-
/** True when an acceptance-report signal was found but its envelope was invalid. */
|
|
856
|
-
malformed?: boolean;
|
|
857
|
-
sourcePath?: string;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
function parseUnterminatedAcceptanceReportFence(output: string): AcceptanceReportParseResult {
|
|
861
|
-
const opener = /```acceptance[-_]report\b[^\n]*\n/gi.exec(output);
|
|
862
|
-
if (!opener) return {};
|
|
863
|
-
const bodyStart = opener.index + opener[0].length;
|
|
864
|
-
if (output.indexOf("```", bodyStart) !== -1) return {};
|
|
865
|
-
try {
|
|
866
|
-
const validation = validateAcceptanceReport(JSON.parse(output.slice(bodyStart).trim()) as unknown);
|
|
867
|
-
return validation.report
|
|
868
|
-
? { report: validation.report }
|
|
869
|
-
: { error: `Failed to parse acceptance-report: Invalid acceptance-report: ${validation.errors.join("; ")}`, malformed: true };
|
|
870
|
-
} catch (error) {
|
|
871
|
-
return { error: `Failed to parse acceptance-report: ${error instanceof Error ? error.message : String(error)}`, malformed: true };
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
function parseGenericJsonAcceptanceReportBody(body: string): AcceptanceReportParseResult {
|
|
876
|
-
const parsed = parseReportJson(body);
|
|
877
|
-
const normalized = normalizeAcceptanceReportValue(parsed);
|
|
878
|
-
const hasCriteriaMarker = normalized.value !== null
|
|
879
|
-
&& typeof normalized.value === "object"
|
|
880
|
-
&& !Array.isArray(normalized.value)
|
|
881
|
-
&& "criteriaSatisfied" in normalized.value;
|
|
882
|
-
if (!hasGenericAcceptanceReportSignal(normalized.value) && !(hasCriteriaMarker && normalized.errors.length > 0)) return {};
|
|
883
|
-
const validation = validateAcceptanceReport(parsed);
|
|
884
|
-
return validation.report
|
|
885
|
-
? { report: validation.report }
|
|
886
|
-
: { error: `Invalid acceptance-report: ${validation.errors.join("; ")}`, malformed: true };
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
export const ACCEPTANCE_REPORT_NOT_FOUND = "Structured acceptance report not found.";
|
|
890
|
-
|
|
891
|
-
export function parseAcceptanceReport(output: string): AcceptanceReportParseResult {
|
|
892
|
-
const explicitFencePresent = /```acceptance[-_]report\b/i.test(output);
|
|
893
|
-
const fenced = fencedBlocks(output, "acceptance[-_]report");
|
|
894
|
-
const parseErrors: string[] = [];
|
|
895
|
-
for (const body of fenced) {
|
|
896
|
-
try {
|
|
897
|
-
const validation = parseAcceptanceReportBody(body);
|
|
898
|
-
if (validation.report) return { report: validation.report };
|
|
899
|
-
parseErrors.push(`Invalid acceptance-report: ${validation.errors.join("; ")}`);
|
|
900
|
-
} catch (error) {
|
|
901
|
-
parseErrors.push(error instanceof Error ? error.message : String(error));
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (parseErrors.length > 0) return { error: `Failed to parse acceptance-report: ${parseErrors.join("; ")}`, malformed: true };
|
|
905
|
-
if (explicitFencePresent) {
|
|
906
|
-
const recovered = parseUnterminatedAcceptanceReportFence(output);
|
|
907
|
-
if (recovered.report || recovered.error) return recovered;
|
|
908
|
-
return { error: "Failed to parse acceptance-report: Empty or unterminated acceptance-report fence.", malformed: true };
|
|
909
|
-
}
|
|
910
|
-
for (const body of fencedBlocks(output, "(?:json|jsonc|json5)")) {
|
|
911
|
-
try {
|
|
912
|
-
const parsed = parseGenericJsonAcceptanceReportBody(body);
|
|
913
|
-
if (parsed.report) return { report: parsed.report };
|
|
914
|
-
if (parsed.error) return { error: `Failed to parse acceptance-report: ${parsed.error}`, malformed: parsed.malformed };
|
|
915
|
-
} catch {
|
|
916
|
-
// Ignore unrelated malformed generic JSON. A recognizable report shape
|
|
917
|
-
// returns exact validation errors above instead of being mistaken for prose.
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
const markerIndex = output.search(/ACCEPTANCE_REPORT\s*:/i);
|
|
921
|
-
if (markerIndex !== -1) {
|
|
922
|
-
const jsonStart = output.indexOf("{", markerIndex);
|
|
923
|
-
if (jsonStart === -1) {
|
|
924
|
-
return { error: "Failed to parse acceptance-report: Expected a JSON object after ACCEPTANCE_REPORT:.", malformed: true };
|
|
925
|
-
}
|
|
926
|
-
const json = extractBalancedJson(output, jsonStart);
|
|
927
|
-
if (!json) {
|
|
928
|
-
return { error: "Failed to parse acceptance-report: Unterminated JSON object after ACCEPTANCE_REPORT:.", malformed: true };
|
|
929
|
-
}
|
|
930
|
-
try {
|
|
931
|
-
const parsed = JSON.parse(json) as unknown;
|
|
932
|
-
const validation = validateAcceptanceReport(parsed);
|
|
933
|
-
if (validation.report) return { report: validation.report };
|
|
934
|
-
return { error: `Failed to parse acceptance-report: Invalid acceptance-report: ${validation.errors.join("; ")}`, malformed: true };
|
|
935
|
-
} catch (error) {
|
|
936
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
937
|
-
return { error: `Failed to parse acceptance-report: ${message}`, malformed: true };
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return { error: ACCEPTANCE_REPORT_NOT_FOUND };
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
function parseAcceptanceReportSources(
|
|
944
|
-
output: string,
|
|
945
|
-
fileOutput: { content: string; path: string; authoritative?: boolean } | undefined,
|
|
946
|
-
): AcceptanceReportParseResult {
|
|
947
|
-
const fromText = () => parseAcceptanceReport(output);
|
|
948
|
-
const fromFile = () => {
|
|
949
|
-
if (!fileOutput) return { error: ACCEPTANCE_REPORT_NOT_FOUND };
|
|
950
|
-
const parsed = parseAcceptanceReport(fileOutput.content);
|
|
951
|
-
return parsed.report || parsed.error === ACCEPTANCE_REPORT_NOT_FOUND
|
|
952
|
-
? parsed
|
|
953
|
-
: {
|
|
954
|
-
...parsed,
|
|
955
|
-
error: `${parsed.error} (in configured output ${fileOutput.path})`,
|
|
956
|
-
sourcePath: fileOutput.path,
|
|
957
|
-
};
|
|
958
|
-
};
|
|
959
|
-
const [primary, secondary] = fileOutput?.authoritative ? [fromFile, fromText] : [fromText, fromFile];
|
|
960
|
-
const first = primary();
|
|
961
|
-
// A malformed report in the primary source is a defect to surface, not a
|
|
962
|
-
// miss to paper over with the secondary source; only a genuinely absent
|
|
963
|
-
// report falls through.
|
|
964
|
-
if (first.report || first.error !== ACCEPTANCE_REPORT_NOT_FOUND) return first;
|
|
965
|
-
return secondary();
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
export function stripAcceptanceReport(output: string): string {
|
|
969
|
-
const trailingFencePattern = /\n?```(acceptance[-_]report|json|jsonc|json5)\s*\n([\s\S]*?)```\s*/gi;
|
|
970
|
-
let trailingFence: { index: number; tag: string; body: string } | undefined;
|
|
971
|
-
for (const match of output.matchAll(trailingFencePattern)) {
|
|
972
|
-
const end = (match.index ?? 0) + match[0].length;
|
|
973
|
-
if (output.slice(end).trim().length === 0 && match[1] && match[2]) {
|
|
974
|
-
trailingFence = { index: match.index ?? 0, tag: match[1].toLowerCase(), body: match[2] };
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
if (trailingFence) {
|
|
978
|
-
if (trailingFence.tag === "acceptance-report" || trailingFence.tag === "acceptance_report") return output.slice(0, trailingFence.index).trimEnd();
|
|
979
|
-
try {
|
|
980
|
-
if (parseGenericJsonAcceptanceReportBody(trailingFence.body).report) return output.slice(0, trailingFence.index).trimEnd();
|
|
981
|
-
} catch {
|
|
982
|
-
// Leave unrelated or malformed generic JSON fences visible.
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return output
|
|
986
|
-
.replace(/\n?```acceptance[-_]report\s*\n[\s\S]*?```\s*$/i, "")
|
|
987
|
-
.replace(/\n?ACCEPTANCE_REPORT\s*:\s*\{[\s\S]*\}\s*$/i, "")
|
|
988
|
-
.trimEnd();
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
function isStringArray(value: unknown): value is string[] {
|
|
992
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
function pathFor(base: string, segment: string): string {
|
|
996
|
-
return base ? `${base}.${segment}` : segment;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
function describeValidationValue(value: unknown): string {
|
|
1000
|
-
if (value === undefined) return "missing";
|
|
1001
|
-
if (value === null) return "null";
|
|
1002
|
-
if (Array.isArray(value)) return "array";
|
|
1003
|
-
if (typeof value === "object") return "object";
|
|
1004
|
-
if (typeof value === "string") {
|
|
1005
|
-
const short = value.length > 80 ? `${value.slice(0, 77)}...` : value;
|
|
1006
|
-
return JSON.stringify(short);
|
|
1007
|
-
}
|
|
1008
|
-
return `${typeof value} ${String(value)}`;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
function pushTypeError(errors: string[], pathLabel: string, expected: string, value: unknown): void {
|
|
1012
|
-
errors.push(`${pathLabel}: expected ${expected}; got ${describeValidationValue(value)}`);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
function validateStringArrayField(errors: string[], value: unknown, pathLabel: string): void {
|
|
1016
|
-
if (!Array.isArray(value)) {
|
|
1017
|
-
pushTypeError(errors, pathLabel, "string[]", value);
|
|
1018
|
-
return;
|
|
1019
|
-
}
|
|
1020
|
-
for (const [index, item] of value.entries()) {
|
|
1021
|
-
if (typeof item !== "string" || !item.trim()) pushTypeError(errors, `${pathLabel}[${index}]`, "non-empty string", item);
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
export function validateAcceptanceReport(value: unknown, pathLabel = ""): { report?: AcceptanceReport; errors: string[] } {
|
|
1026
|
-
const normalized = normalizeAcceptanceReportValue(value, pathLabel);
|
|
1027
|
-
value = normalized.value;
|
|
1028
|
-
pathLabel = normalized.pathLabel;
|
|
1029
|
-
const errors = normalized.errors;
|
|
1030
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1031
|
-
pushTypeError(errors, pathLabel || "acceptance-report", "object", value);
|
|
1032
|
-
return { errors };
|
|
1033
|
-
}
|
|
1034
|
-
const report = value as AcceptanceReport;
|
|
1035
|
-
if (report.criteriaSatisfied !== undefined) {
|
|
1036
|
-
if (!Array.isArray(report.criteriaSatisfied)) {
|
|
1037
|
-
pushTypeError(errors, pathFor(pathLabel, "criteriaSatisfied"), "array", report.criteriaSatisfied);
|
|
1038
|
-
} else {
|
|
1039
|
-
const criterionIds = new Set<string>();
|
|
1040
|
-
for (const [index, item] of report.criteriaSatisfied.entries()) {
|
|
1041
|
-
const itemPath = `${pathFor(pathLabel, "criteriaSatisfied")}[${index}]`;
|
|
1042
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
1043
|
-
pushTypeError(errors, itemPath, "object", item);
|
|
1044
|
-
continue;
|
|
1045
|
-
}
|
|
1046
|
-
const criterion = item as { id?: unknown; status?: unknown; evidence?: unknown };
|
|
1047
|
-
if (criterion.id !== undefined && typeof criterion.id !== "string") {
|
|
1048
|
-
pushTypeError(errors, `${itemPath}.id`, "string", criterion.id);
|
|
1049
|
-
} else if (typeof criterion.id === "string" && criterion.id) {
|
|
1050
|
-
if (criterionIds.has(criterion.id)) errors.push(`${itemPath}.id: duplicate normalized criterion id '${criterion.id}'`);
|
|
1051
|
-
criterionIds.add(criterion.id);
|
|
1052
|
-
}
|
|
1053
|
-
if (criterion.status !== "satisfied" && criterion.status !== "not-satisfied" && criterion.status !== "not-applicable") {
|
|
1054
|
-
pushTypeError(errors, `${itemPath}.status`, "one of \"satisfied\", \"not-satisfied\", \"not-applicable\"", criterion.status);
|
|
1055
|
-
}
|
|
1056
|
-
if (typeof criterion.evidence !== "string" || !criterion.evidence.trim()) pushTypeError(errors, `${itemPath}.evidence`, "non-empty string", criterion.evidence);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
if (report.changedFiles !== undefined) validateStringArrayField(errors, report.changedFiles, pathFor(pathLabel, "changedFiles"));
|
|
1061
|
-
if (report.testsAddedOrUpdated !== undefined) validateStringArrayField(errors, report.testsAddedOrUpdated, pathFor(pathLabel, "testsAddedOrUpdated"));
|
|
1062
|
-
if (report.commandsRun !== undefined) {
|
|
1063
|
-
if (!Array.isArray(report.commandsRun)) {
|
|
1064
|
-
pushTypeError(errors, pathFor(pathLabel, "commandsRun"), "array", report.commandsRun);
|
|
1065
|
-
} else {
|
|
1066
|
-
for (const [index, item] of report.commandsRun.entries()) {
|
|
1067
|
-
const itemPath = `${pathFor(pathLabel, "commandsRun")}[${index}]`;
|
|
1068
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
1069
|
-
pushTypeError(errors, itemPath, "object", item);
|
|
1070
|
-
continue;
|
|
1071
|
-
}
|
|
1072
|
-
const command = item as { command?: unknown; result?: unknown; summary?: unknown };
|
|
1073
|
-
if (typeof command.command !== "string" || !command.command.trim()) pushTypeError(errors, `${itemPath}.command`, "non-empty string", command.command);
|
|
1074
|
-
if (command.result !== "passed" && command.result !== "failed" && command.result !== "not-run") {
|
|
1075
|
-
pushTypeError(errors, `${itemPath}.result`, "one of \"passed\", \"failed\", \"not-run\"", command.result);
|
|
1076
|
-
}
|
|
1077
|
-
if (typeof command.summary !== "string" || !command.summary.trim()) pushTypeError(errors, `${itemPath}.summary`, "non-empty string", command.summary);
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
if (report.validationOutput !== undefined) validateStringArrayField(errors, report.validationOutput, pathFor(pathLabel, "validationOutput"));
|
|
1082
|
-
if (report.residualRisks !== undefined) validateStringArrayField(errors, report.residualRisks, pathFor(pathLabel, "residualRisks"));
|
|
1083
|
-
if (report.noStagedFiles !== undefined && typeof report.noStagedFiles !== "boolean") pushTypeError(errors, pathFor(pathLabel, "noStagedFiles"), "boolean", report.noStagedFiles);
|
|
1084
|
-
if (report.diffSummary !== undefined && (typeof report.diffSummary !== "string" || !report.diffSummary.trim())) pushTypeError(errors, pathFor(pathLabel, "diffSummary"), "non-empty string", report.diffSummary);
|
|
1085
|
-
if (report.reviewFindings !== undefined) validateStringArrayField(errors, report.reviewFindings, pathFor(pathLabel, "reviewFindings"));
|
|
1086
|
-
if (report.manualNotes !== undefined && typeof report.manualNotes !== "string") pushTypeError(errors, pathFor(pathLabel, "manualNotes"), "string", report.manualNotes);
|
|
1087
|
-
if (report.notes !== undefined && typeof report.notes !== "string") pushTypeError(errors, pathFor(pathLabel, "notes"), "string", report.notes);
|
|
1088
|
-
if (errors.length > 0) return { errors };
|
|
1089
|
-
const hasReportField = report.criteriaSatisfied !== undefined
|
|
1090
|
-
|| report.changedFiles !== undefined
|
|
1091
|
-
|| report.testsAddedOrUpdated !== undefined
|
|
1092
|
-
|| report.commandsRun !== undefined
|
|
1093
|
-
|| report.validationOutput !== undefined
|
|
1094
|
-
|| report.residualRisks !== undefined
|
|
1095
|
-
|| report.noStagedFiles !== undefined
|
|
1096
|
-
|| report.diffSummary !== undefined
|
|
1097
|
-
|| report.manualNotes !== undefined
|
|
1098
|
-
|| report.notes !== undefined
|
|
1099
|
-
|| report.reviewFindings !== undefined;
|
|
1100
|
-
return hasReportField
|
|
1101
|
-
? { report, errors }
|
|
1102
|
-
: { errors: [`${pathLabel || "acceptance-report"}: expected at least one acceptance report field`] };
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
function checkCriteriaSatisfied(criteria: ResolvedAcceptanceGate[], report: AcceptanceReport): AcceptanceRuntimeCheck[] {
|
|
1106
|
-
const reports = new Map((report.criteriaSatisfied ?? []).filter((item) => item.id).map((item) => [normalizedToken(item.id!), item]));
|
|
1107
|
-
return criteria.filter((criterion) => criterion.severity !== "recommended").map((criterion) => {
|
|
1108
|
-
const item = reports.get(normalizedToken(criterion.id));
|
|
1109
|
-
if (!item) return { id: `criterion:${criterion.id}`, status: "failed", message: `Required criterion '${criterion.id}' was not reported.` };
|
|
1110
|
-
if (item.status !== "satisfied") return { id: `criterion:${criterion.id}`, status: "failed", message: `Required criterion '${criterion.id}' was reported as ${item.status}.` };
|
|
1111
|
-
return { id: `criterion:${criterion.id}`, status: "passed", message: `Required criterion '${criterion.id}' satisfied.` };
|
|
1112
|
-
});
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
function reportEvidenceStatus(report: AcceptanceReport, kind: AcceptanceEvidenceKind): AcceptanceRuntimeCheckStatus {
|
|
1116
|
-
switch (kind) {
|
|
1117
|
-
case "changed-files":
|
|
1118
|
-
if (!isStringArray(report.changedFiles)) return "failed";
|
|
1119
|
-
return report.changedFiles.length === 0 ? "not-applicable" : "passed";
|
|
1120
|
-
case "tests-added":
|
|
1121
|
-
if (!isStringArray(report.testsAddedOrUpdated)) return "failed";
|
|
1122
|
-
return report.testsAddedOrUpdated.length === 0 ? "not-applicable" : "passed";
|
|
1123
|
-
case "commands-run": return Array.isArray(report.commandsRun) && report.commandsRun.length > 0 ? "passed" : "failed";
|
|
1124
|
-
case "validation-output": return isStringArray(report.validationOutput) && report.validationOutput.length > 0 ? "passed" : "failed";
|
|
1125
|
-
case "residual-risks": return isStringArray(report.residualRisks) ? "passed" : "failed";
|
|
1126
|
-
case "no-staged-files": return report.noStagedFiles === true ? "passed" : "failed";
|
|
1127
|
-
case "diff-summary": return typeof report.diffSummary === "string" && report.diffSummary.trim().length > 0 ? "passed" : "failed";
|
|
1128
|
-
case "review-findings": return isStringArray(report.reviewFindings) ? "passed" : "failed";
|
|
1129
|
-
case "manual-notes": return Boolean((report.manualNotes ?? report.notes)?.trim()) ? "passed" : "failed";
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
function checkNoStagedFiles(cwd: string): AcceptanceRuntimeCheck {
|
|
1134
|
-
const result = spawnSync("git", ["status", "--short"], { cwd, encoding: "utf-8", windowsHide: true });
|
|
1135
|
-
if (result.status !== 0) {
|
|
1136
|
-
return { id: "no-staged-files", status: "not-applicable", message: "git status unavailable; no staged-files check skipped" };
|
|
1137
|
-
}
|
|
1138
|
-
const staged = result.stdout.split(/\r?\n/).filter((line) => line.length >= 2 && line[0] !== " " && line[0] !== "?");
|
|
1139
|
-
return staged.length === 0
|
|
1140
|
-
? { id: "no-staged-files", status: "passed", message: "No staged files detected." }
|
|
1141
|
-
: { id: "no-staged-files", status: "failed", message: `Staged files present: ${staged.join(", ")}` };
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
/** Capture the repository-wide index tree. Throws when Git cannot provide trustworthy evidence. */
|
|
1145
|
-
export function captureStagedIndexBaseline(cwd: string): string {
|
|
1146
|
-
const result = spawnSync("git", ["write-tree"], { cwd, encoding: "utf-8", windowsHide: true });
|
|
1147
|
-
const oid = result.stdout.trim();
|
|
1148
|
-
if (result.status !== 0 || !oid) {
|
|
1149
|
-
const detail = result.stderr.trim();
|
|
1150
|
-
throw new Error(`Unable to capture staged index baseline${detail ? `: ${detail}` : "."}`);
|
|
1151
|
-
}
|
|
1152
|
-
return oid;
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
function checkStagedIndexUnchanged(cwd: string, baseline: string): AcceptanceRuntimeCheck {
|
|
1156
|
-
try {
|
|
1157
|
-
const terminal = captureStagedIndexBaseline(cwd);
|
|
1158
|
-
return terminal === baseline
|
|
1159
|
-
? { id: "staged-index-unchanged", status: "passed", message: "Staged index matches the launch baseline." }
|
|
1160
|
-
: { id: "staged-index-unchanged", status: "failed", message: "Staged index changed after launch." };
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
return { id: "staged-index-unchanged", status: "failed", message: error instanceof Error ? error.message : String(error) };
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
function runStructuralChecks(acceptance: ResolvedAcceptanceConfig, report: AcceptanceReport, cwd: string): AcceptanceRuntimeCheck[] {
|
|
1167
|
-
const checks: AcceptanceRuntimeCheck[] = [];
|
|
1168
|
-
for (const kind of acceptance.evidence) {
|
|
1169
|
-
if (kind === "no-staged-files" && acceptance.preserveStagedIndex) continue;
|
|
1170
|
-
if (kind === "no-staged-files" && report.noStagedFiles === undefined) continue;
|
|
1171
|
-
const status = reportEvidenceStatus(report, kind);
|
|
1172
|
-
checks.push({
|
|
1173
|
-
id: `evidence:${kind}`,
|
|
1174
|
-
status,
|
|
1175
|
-
message: status === "passed"
|
|
1176
|
-
? `${kind} evidence present.`
|
|
1177
|
-
: status === "not-applicable"
|
|
1178
|
-
? `${kind} evidence explicitly reported as not applicable.`
|
|
1179
|
-
: `${kind} evidence missing from child report.`,
|
|
1180
|
-
});
|
|
1181
|
-
}
|
|
1182
|
-
if (!acceptance.preserveStagedIndex && acceptance.evidence.includes("no-staged-files")) checks.push(checkNoStagedFiles(cwd));
|
|
1183
|
-
return checks;
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
function trimOutput(value: string): string | undefined {
|
|
1187
|
-
const trimmed = value.trim();
|
|
1188
|
-
if (!trimmed) return undefined;
|
|
1189
|
-
return trimmed.length > 12_000 ? `${trimmed.slice(0, 12_000)}\n...[truncated]` : trimmed;
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
const SENSITIVE_ENV_KEY_PATTERN = /(?:^|_)(?:TOKEN|SECRET|PASSWORD|PASS|AUTH|CREDENTIAL|COOKIE|SESSION|PRIVATE|API_KEY|ACCESS_KEY)(?:_|$)/i;
|
|
1193
|
-
|
|
1194
|
-
function effectiveVerifyEnv(env: Record<string, string> | undefined): Record<string, string> {
|
|
1195
|
-
const inherited = Object.fromEntries(Object.entries(process.env).flatMap(([key, value]) => {
|
|
1196
|
-
return typeof value === "string" ? [[key, value]] : [];
|
|
1197
|
-
}));
|
|
1198
|
-
return { ...inherited, ...(env ?? {}) };
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
function verifyRedactionEnv(env: Record<string, string> | undefined): Record<string, string> {
|
|
1202
|
-
return Object.fromEntries(Object.entries(effectiveVerifyEnv(env)).filter(([key, value]) => {
|
|
1203
|
-
return value.length >= 4 && SENSITIVE_ENV_KEY_PATTERN.test(key);
|
|
1204
|
-
}));
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
function redactVerifyEnv(value: string, env: Record<string, string> | undefined): string {
|
|
1208
|
-
let redacted = value;
|
|
1209
|
-
const secrets = [...new Set(Object.values(verifyRedactionEnv(env)).filter(Boolean))].sort((left, right) => right.length - left.length);
|
|
1210
|
-
for (const secret of secrets) redacted = redacted.replaceAll(secret, "[REDACTED]");
|
|
1211
|
-
return redacted;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
function uniqueStrings(items: Array<string | undefined>): string[] {
|
|
1215
|
-
return unique(items.map((item) => item?.trim()).filter((item): item is string => Boolean(item)));
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
export function aggregateAcceptanceReport(input: {
|
|
1219
|
-
results: Array<Pick<SingleResult, "agent" | "acceptance" | "error"> & { exitCode: number | null }>;
|
|
1220
|
-
notes?: string;
|
|
1221
|
-
}): AcceptanceReport {
|
|
1222
|
-
const childReports = input.results.map((result) => result.acceptance?.childReport).filter((report): report is AcceptanceReport => Boolean(report));
|
|
1223
|
-
const blockers = input.results.filter((result) => result.exitCode !== 0 || result.acceptance?.status === "rejected");
|
|
1224
|
-
const successfulChildren = input.results.length > 0 && blockers.length === 0;
|
|
1225
|
-
return {
|
|
1226
|
-
criteriaSatisfied: [
|
|
1227
|
-
{ id: "criterion-1", status: successfulChildren ? "satisfied" : "not-satisfied", evidence: successfulChildren ? `All ${input.results.length} dynamic child run(s) completed without child or acceptance blockers.` : "Dynamic fanout produced no accepted child evidence." },
|
|
1228
|
-
{ id: "criterion-2", status: successfulChildren ? "satisfied" : "not-satisfied", evidence: successfulChildren ? "Collected child acceptance evidence for aggregate review." : "Dynamic fanout produced no aggregate review evidence." },
|
|
1229
|
-
...input.results.map((result, index): { id?: string; status: "satisfied" | "not-satisfied" | "not-applicable"; evidence: string } => ({
|
|
1230
|
-
id: `child-${index + 1}`,
|
|
1231
|
-
status: result.exitCode === 0 && result.acceptance?.status !== "rejected" ? "satisfied" : "not-satisfied",
|
|
1232
|
-
evidence: `${result.agent}: acceptance ${result.acceptance?.status ?? "unreported"}${result.error ? ` (${result.error})` : ""}`,
|
|
1233
|
-
})),
|
|
1234
|
-
],
|
|
1235
|
-
changedFiles: uniqueStrings(childReports.flatMap((report) => report.changedFiles ?? [])),
|
|
1236
|
-
testsAddedOrUpdated: uniqueStrings(childReports.flatMap((report) => report.testsAddedOrUpdated ?? [])),
|
|
1237
|
-
commandsRun: childReports.flatMap((report) => report.commandsRun ?? []),
|
|
1238
|
-
validationOutput: uniqueStrings(childReports.flatMap((report) => report.validationOutput ?? [])),
|
|
1239
|
-
residualRisks: uniqueStrings([
|
|
1240
|
-
...childReports.flatMap((report) => report.residualRisks ?? []),
|
|
1241
|
-
...blockers.map((result) => `${result.agent}: ${result.error ?? "child or acceptance gate failed"}`),
|
|
1242
|
-
]),
|
|
1243
|
-
noStagedFiles: childReports.length > 0 && childReports.every((report) => report.noStagedFiles === true),
|
|
1244
|
-
reviewFindings: uniqueStrings(childReports.flatMap((report) => report.reviewFindings ?? [])),
|
|
1245
|
-
manualNotes: input.notes ?? `Aggregated acceptance evidence from ${input.results.length} dynamic fanout child run(s).`,
|
|
1246
|
-
notes: input.notes,
|
|
1247
|
-
};
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
const DEFAULT_VERIFY_TIMEOUT_MS = 120_000;
|
|
1251
|
-
|
|
1252
|
-
function hash(value: string): string {
|
|
1253
|
-
return createHash("sha256").update(value).digest("hex");
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
interface VerifyWorkspaceState {
|
|
1257
|
-
kind: "git-tracked";
|
|
1258
|
-
repoRoot: string;
|
|
1259
|
-
cwdRelative: string;
|
|
1260
|
-
head: string;
|
|
1261
|
-
diffHash: string;
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
function readVerifyWorkspaceState(cwd: string): VerifyWorkspaceState | undefined {
|
|
1265
|
-
const repo = spawnSync("git", ["rev-parse", "--show-toplevel"], { cwd, encoding: "utf-8", windowsHide: true });
|
|
1266
|
-
if (repo.status !== 0 || !repo.stdout.trim()) return undefined;
|
|
1267
|
-
const repoRoot = fs.realpathSync(repo.stdout.trim());
|
|
1268
|
-
const head = spawnSync("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf-8", windowsHide: true });
|
|
1269
|
-
const diff = spawnSync("git", ["diff", "--binary", "--full-index", "HEAD", "--"], { cwd: repoRoot, encoding: "utf-8", maxBuffer: 50 * 1024 * 1024, windowsHide: true });
|
|
1270
|
-
if (head.status !== 0 || diff.status !== 0 || !head.stdout.trim()) return undefined;
|
|
1271
|
-
return {
|
|
1272
|
-
kind: "git-tracked",
|
|
1273
|
-
repoRoot,
|
|
1274
|
-
cwdRelative: path.relative(repoRoot, fs.realpathSync(cwd)) || ".",
|
|
1275
|
-
head: head.stdout.trim(),
|
|
1276
|
-
diffHash: hash(diff.stdout),
|
|
1277
|
-
};
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
function isCachedVerifyResult(value: unknown): value is AcceptanceVerifyResult {
|
|
1281
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1282
|
-
const result = value as Partial<AcceptanceVerifyResult>;
|
|
1283
|
-
return typeof result.id === "string"
|
|
1284
|
-
&& typeof result.command === "string"
|
|
1285
|
-
&& (typeof result.exitCode === "number" || result.exitCode === null)
|
|
1286
|
-
&& (result.status === "passed" || result.status === "failed" || result.status === "timed-out" || result.status === "allowed-failure")
|
|
1287
|
-
&& typeof result.durationMs === "number";
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
const TYPED_VERIFY_OUTPUT_MAX_BYTES = 12_000;
|
|
1291
|
-
|
|
1292
|
-
/**
|
|
1293
|
-
* A passing `output: "json"` command must print one JSON document on stdout.
|
|
1294
|
-
* The parsed value becomes the run's structured output; anything else turns
|
|
1295
|
-
* the passing run into a failed one so acceptance rejects rather than
|
|
1296
|
-
* silently dropping the verdict. Stdout is already bounded by trimOutput, so a
|
|
1297
|
-
* truncated document is detected by its marker instead of a parse guess.
|
|
1298
|
-
*/
|
|
1299
|
-
async function applyTypedVerifyOutput(command: AcceptanceVerifyCommand, run: AcceptanceVerifyResult): Promise<void> {
|
|
1300
|
-
if (run.status !== "passed") return;
|
|
1301
|
-
const stdout = run.stdout ?? "";
|
|
1302
|
-
const fail = (message: string): void => {
|
|
1303
|
-
run.status = "failed";
|
|
1304
|
-
run.structuredOutputError = message;
|
|
1305
|
-
};
|
|
1306
|
-
if (!stdout.trim()) return fail("output: \"json\" command printed nothing on stdout.");
|
|
1307
|
-
if (stdout.endsWith("...[truncated]")) return fail(`output: "json" stdout exceeded ${TYPED_VERIFY_OUTPUT_MAX_BYTES} characters and was truncated.`);
|
|
1308
|
-
let value: unknown;
|
|
1309
|
-
try {
|
|
1310
|
-
value = JSON.parse(stdout);
|
|
1311
|
-
} catch (error) {
|
|
1312
|
-
return fail(`output: "json" stdout is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
1313
|
-
}
|
|
1314
|
-
if (command.schema) {
|
|
1315
|
-
const validation = await validateStructuredOutputValue(command.schema, value);
|
|
1316
|
-
if (validation.status === "invalid") return fail(`output: "json" stdout does not match gate.schema: ${validation.message}`);
|
|
1317
|
-
}
|
|
1318
|
-
run.structuredOutput = value;
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
/** The first typed verify result on a ledger, if any command produced one. */
|
|
1322
|
-
export function typedVerifyOutput(ledger: AcceptanceLedger | undefined): { value: unknown } | undefined {
|
|
1323
|
-
const run = ledger?.verifyRuns?.find((entry) => entry.structuredOutput !== undefined);
|
|
1324
|
-
return run ? { value: run.structuredOutput } : undefined;
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
async function runMemoizedVerifyCommand(command: AcceptanceVerifyCommand, defaultCwd: string, options: {
|
|
1328
|
-
signal?: AbortSignal;
|
|
1329
|
-
abortMessage?: string;
|
|
1330
|
-
artifactsDir?: string;
|
|
1331
|
-
runId?: string;
|
|
1332
|
-
} = {}): Promise<AcceptanceVerifyResult> {
|
|
1333
|
-
const cwd = command.cwd ? path.resolve(defaultCwd, command.cwd) : defaultCwd;
|
|
1334
|
-
let workspaceState: VerifyWorkspaceState | undefined;
|
|
1335
|
-
try {
|
|
1336
|
-
workspaceState = readVerifyWorkspaceState(cwd);
|
|
1337
|
-
} catch {
|
|
1338
|
-
workspaceState = undefined;
|
|
1339
|
-
}
|
|
1340
|
-
// Typed gates read inputs (a report file, a log) that can change without
|
|
1341
|
-
// the tracked tree changing, so their verdicts are never reused.
|
|
1342
|
-
if (!workspaceState || !options.artifactsDir || !options.runId || command.output === "json") {
|
|
1343
|
-
return runVerifyCommand(command, defaultCwd, options);
|
|
1344
|
-
}
|
|
1345
|
-
const envKeys = Object.keys(command.env ?? {}).sort();
|
|
1346
|
-
const envHash = hash(JSON.stringify(Object.fromEntries(Object.entries(effectiveVerifyEnv(command.env)).sort(([left], [right]) => left.localeCompare(right)))));
|
|
1347
|
-
const timeoutMs = command.timeoutMs ?? DEFAULT_VERIFY_TIMEOUT_MS;
|
|
1348
|
-
const cacheKey = hash(JSON.stringify({
|
|
1349
|
-
version: 1,
|
|
1350
|
-
command: command.command,
|
|
1351
|
-
cwdRelative: workspaceState.cwdRelative,
|
|
1352
|
-
envKeys,
|
|
1353
|
-
envHash,
|
|
1354
|
-
timeoutMs,
|
|
1355
|
-
allowFailure: command.allowFailure === true,
|
|
1356
|
-
head: workspaceState.head,
|
|
1357
|
-
diffHash: workspaceState.diffHash,
|
|
1358
|
-
}));
|
|
1359
|
-
const artifactPath = path.join(options.artifactsDir, "acceptance", "verify", options.runId, `${cacheKey}.json`);
|
|
1360
|
-
try {
|
|
1361
|
-
const cached = JSON.parse(fs.readFileSync(artifactPath, "utf-8")) as { cacheKey?: unknown; result?: unknown };
|
|
1362
|
-
if (cached.cacheKey === cacheKey && isCachedVerifyResult(cached.result)) {
|
|
1363
|
-
return { ...cached.result, id: command.id, command: command.command, cwd, artifactPath, cacheKey, memoized: true, envKeys, envHash, workspaceState };
|
|
1364
|
-
}
|
|
1365
|
-
} catch {
|
|
1366
|
-
// A cache miss or unreadable artifact must not prevent host verification.
|
|
1367
|
-
}
|
|
1368
|
-
const result = await runVerifyCommand(command, defaultCwd, options);
|
|
1369
|
-
const evidenced: AcceptanceVerifyResult = { ...result, artifactPath, cacheKey, memoized: false, envKeys, envHash, workspaceState };
|
|
1370
|
-
try {
|
|
1371
|
-
fs.mkdirSync(path.dirname(artifactPath), { recursive: true });
|
|
1372
|
-
fs.writeFileSync(artifactPath, JSON.stringify({
|
|
1373
|
-
version: 1,
|
|
1374
|
-
cacheKey,
|
|
1375
|
-
command: command.command,
|
|
1376
|
-
cwdRelative: workspaceState.cwdRelative,
|
|
1377
|
-
envKeys,
|
|
1378
|
-
envHash,
|
|
1379
|
-
timeoutMs,
|
|
1380
|
-
allowFailure: command.allowFailure === true,
|
|
1381
|
-
workspaceState,
|
|
1382
|
-
result: evidenced,
|
|
1383
|
-
}, null, 2), "utf-8");
|
|
1384
|
-
} catch (error) {
|
|
1385
|
-
evidenced.artifactError = error instanceof Error ? error.message : String(error);
|
|
1386
|
-
delete evidenced.artifactPath;
|
|
1387
|
-
}
|
|
1388
|
-
return evidenced;
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
/**
|
|
1392
|
-
* On Windows with `shell: true`, cmd.exe parses the command line itself and an
|
|
1393
|
-
* unquoted executable path containing spaces (e.g. `C:\Program Files\...\tool.exe`)
|
|
1394
|
-
* is split at the first space, so cmd tries to run `C:\Program` and fails.
|
|
1395
|
-
*
|
|
1396
|
-
* The command line is ambiguous, so only an unquoted absolute drive path with
|
|
1397
|
-
* a space in a directory component is safe to identify as an executable. That
|
|
1398
|
-
* path is quoted; everything after it is preserved as arguments.
|
|
1399
|
-
*
|
|
1400
|
-
* Commands that already start with a quote, single-token commands, and commands
|
|
1401
|
-
* whose first token already ends in an executable extension are returned
|
|
1402
|
-
* unchanged. Non-Windows platforms pass the command through untouched.
|
|
1403
|
-
*/
|
|
1404
|
-
export function quoteExecutableForShell(command: string, platform: string = process.platform): string {
|
|
1405
|
-
if (platform !== "win32") return command;
|
|
1406
|
-
const trimmed = command.trimStart();
|
|
1407
|
-
if (trimmed.startsWith("\"")) return command;
|
|
1408
|
-
const firstToken = trimmed.match(/^\S+/)?.[0];
|
|
1409
|
-
if (/\.(?:exe|bat|cmd|com|ps1)$/i.test(firstToken ?? "")) return command;
|
|
1410
|
-
const match = trimmed.match(/^([A-Za-z]:\\[^"<>|&*?\r\n]*?\s[^"<>|&*?\r\n]*?\\[^"<>|&*?\r\n]*?\.(?:exe|bat|cmd|com|ps1))(?=\s|$)/i);
|
|
1411
|
-
const executable = match?.[1];
|
|
1412
|
-
if (executable && /\s/.test(executable) && !/[A-Za-z]:\\/.test(executable.slice(3))) {
|
|
1413
|
-
const rest = trimmed.slice(executable.length);
|
|
1414
|
-
const leading = command.slice(0, command.length - trimmed.length);
|
|
1415
|
-
return `${leading}"${executable}"${rest}`;
|
|
1416
|
-
}
|
|
1417
|
-
const extensionlessSpacedFilenameMatch = trimmed.match(/^([A-Za-z]:\\[^"<>|&*?\r\n]*?\s[^"<>|&*?\r\n]*?)(?=\s+--|$)/i);
|
|
1418
|
-
const extensionlessSpacedFilename = extensionlessSpacedFilenameMatch?.[1];
|
|
1419
|
-
if (extensionlessSpacedFilename && /\s/.test(extensionlessSpacedFilename.slice(0, extensionlessSpacedFilename.lastIndexOf("\\"))) && !/[A-Za-z]:\\/.test(extensionlessSpacedFilename.slice(3))) {
|
|
1420
|
-
const rest = trimmed.slice(extensionlessSpacedFilename.length);
|
|
1421
|
-
const leading = command.slice(0, command.length - trimmed.length);
|
|
1422
|
-
return `${leading}"${extensionlessSpacedFilename}"${rest}`;
|
|
1423
|
-
}
|
|
1424
|
-
const extensionlessMatch = trimmed.match(/^([A-Za-z]:\\[^"<>|&*?\r\n]*?\s[^"<>|&*?\r\n]*?\\[^"<>|&*?\s\r\n]+)(?=\s|$)/i);
|
|
1425
|
-
const extensionlessExecutable = extensionlessMatch?.[1];
|
|
1426
|
-
if (extensionlessExecutable && /\s/.test(extensionlessExecutable) && !/[A-Za-z]:\\/.test(extensionlessExecutable.slice(3)) && !/\s/.test(extensionlessExecutable.slice(extensionlessExecutable.lastIndexOf("\\") + 1))) {
|
|
1427
|
-
const rest = trimmed.slice(extensionlessExecutable.length);
|
|
1428
|
-
const leading = command.slice(0, command.length - trimmed.length);
|
|
1429
|
-
return `${leading}"${extensionlessExecutable}"${rest}`;
|
|
1430
|
-
}
|
|
1431
|
-
return command;
|
|
1432
|
-
}
|
|
1433
|
-
|
|
1434
|
-
function runVerifyCommand(command: AcceptanceVerifyCommand, defaultCwd: string, options: { signal?: AbortSignal; abortMessage?: string } = {}): Promise<AcceptanceVerifyResult> {
|
|
1435
|
-
return new Promise((resolve) => {
|
|
1436
|
-
const startedAt = Date.now();
|
|
1437
|
-
const cwd = command.cwd ? path.resolve(defaultCwd, command.cwd) : defaultCwd;
|
|
1438
|
-
let stdout = "";
|
|
1439
|
-
let stderr = "";
|
|
1440
|
-
let timedOut = false;
|
|
1441
|
-
let settled = false;
|
|
1442
|
-
let hardKill: NodeJS.Timeout | undefined;
|
|
1443
|
-
const child = spawn(quoteExecutableForShell(command.command), {
|
|
1444
|
-
cwd,
|
|
1445
|
-
env: effectiveVerifyEnv(command.env),
|
|
1446
|
-
shell: true,
|
|
1447
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1448
|
-
windowsHide: true,
|
|
1449
|
-
});
|
|
1450
|
-
const finish = (result: Omit<AcceptanceVerifyResult, "id" | "command" | "cwd" | "durationMs">) => {
|
|
1451
|
-
if (settled) return;
|
|
1452
|
-
settled = true;
|
|
1453
|
-
clearTimeout(timeout);
|
|
1454
|
-
if (hardKill) clearTimeout(hardKill);
|
|
1455
|
-
options.signal?.removeEventListener("abort", abortVerification);
|
|
1456
|
-
resolve({
|
|
1457
|
-
id: command.id,
|
|
1458
|
-
command: command.command,
|
|
1459
|
-
cwd,
|
|
1460
|
-
durationMs: Date.now() - startedAt,
|
|
1461
|
-
...result,
|
|
1462
|
-
});
|
|
1463
|
-
};
|
|
1464
|
-
const abortVerification = () => {
|
|
1465
|
-
if (settled || timedOut) return;
|
|
1466
|
-
timedOut = true;
|
|
1467
|
-
child.kill("SIGTERM");
|
|
1468
|
-
hardKill = setTimeout(() => {
|
|
1469
|
-
child.kill("SIGKILL");
|
|
1470
|
-
finish({
|
|
1471
|
-
exitCode: null,
|
|
1472
|
-
status: "timed-out",
|
|
1473
|
-
stdout: trimOutput(redactVerifyEnv(stdout, command.env)),
|
|
1474
|
-
stderr: trimOutput(redactVerifyEnv(stderr || options.abortMessage || "Acceptance verification timed out.", command.env)),
|
|
1475
|
-
});
|
|
1476
|
-
}, 1000);
|
|
1477
|
-
hardKill.unref?.();
|
|
1478
|
-
};
|
|
1479
|
-
const timeout = setTimeout(abortVerification, command.timeoutMs ?? DEFAULT_VERIFY_TIMEOUT_MS);
|
|
1480
|
-
timeout.unref?.();
|
|
1481
|
-
if (options.signal?.aborted) abortVerification();
|
|
1482
|
-
else options.signal?.addEventListener("abort", abortVerification, { once: true });
|
|
1483
|
-
child.stdout.on("data", (chunk: Buffer) => {
|
|
1484
|
-
stdout += chunk.toString();
|
|
1485
|
-
});
|
|
1486
|
-
child.stderr.on("data", (chunk: Buffer) => {
|
|
1487
|
-
stderr += chunk.toString();
|
|
1488
|
-
});
|
|
1489
|
-
child.on("close", (exitCode) => {
|
|
1490
|
-
const passed = exitCode === 0 && !timedOut;
|
|
1491
|
-
finish({
|
|
1492
|
-
exitCode,
|
|
1493
|
-
status: timedOut ? "timed-out" : passed ? "passed" : command.allowFailure ? "allowed-failure" : "failed",
|
|
1494
|
-
stdout: trimOutput(redactVerifyEnv(stdout, command.env)),
|
|
1495
|
-
stderr: trimOutput(redactVerifyEnv(stderr || (timedOut ? options.abortMessage ?? "" : ""), command.env)),
|
|
1496
|
-
});
|
|
1497
|
-
});
|
|
1498
|
-
child.on("error", (error) => {
|
|
1499
|
-
finish({
|
|
1500
|
-
exitCode: timedOut ? null : 1,
|
|
1501
|
-
status: timedOut ? "timed-out" : command.allowFailure ? "allowed-failure" : "failed",
|
|
1502
|
-
stderr: timedOut
|
|
1503
|
-
? trimOutput(redactVerifyEnv(stderr || options.abortMessage || "Acceptance verification timed out.", command.env))
|
|
1504
|
-
: redactVerifyEnv(error instanceof Error ? error.message : String(error), command.env),
|
|
1505
|
-
});
|
|
1506
|
-
});
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
export async function evaluateAcceptance(input: {
|
|
1511
|
-
acceptance: ResolvedAcceptanceConfig;
|
|
1512
|
-
output: string;
|
|
1513
|
-
cwd: string;
|
|
1514
|
-
/** Host-captured launch index tree; required by preserveStagedIndex. */
|
|
1515
|
-
stagedIndexBaseline?: string;
|
|
1516
|
-
/**
|
|
1517
|
-
* Content the child sent to its configured output file (from its own write
|
|
1518
|
-
* tool calls, not from disk, so a concurrent writer to the same path cannot
|
|
1519
|
-
* be misattributed). Searched for the acceptance report; searched before
|
|
1520
|
-
* the assistant output when `authoritative` (outputMode "file-only").
|
|
1521
|
-
*/
|
|
1522
|
-
fileOutput?: { content: string; path: string; authoritative?: boolean; durable?: boolean };
|
|
1523
|
-
report?: AcceptanceReport;
|
|
1524
|
-
reportError?: string;
|
|
1525
|
-
reviewResult?: AcceptanceReviewResult;
|
|
1526
|
-
signal?: AbortSignal;
|
|
1527
|
-
abortMessage?: string;
|
|
1528
|
-
reportOptional?: boolean;
|
|
1529
|
-
artifactsDir?: string;
|
|
1530
|
-
runId?: string;
|
|
1531
|
-
watchdog?: ChildWatchdogProgress;
|
|
1532
|
-
}): Promise<AcceptanceLedger> {
|
|
1533
|
-
const acceptance = input.acceptance;
|
|
1534
|
-
const initialStatus = acceptance.level === "none" ? "not-required" : "claimed";
|
|
1535
|
-
const ledger: AcceptanceLedger = {
|
|
1536
|
-
status: initialStatus,
|
|
1537
|
-
evidenceStatus: initialStatus,
|
|
1538
|
-
explicit: acceptance.explicit,
|
|
1539
|
-
effectiveAcceptance: acceptance,
|
|
1540
|
-
inferredReason: acceptance.inferredReason,
|
|
1541
|
-
criteria: acceptance.criteria,
|
|
1542
|
-
runtimeChecks: [],
|
|
1543
|
-
verifyRuns: [],
|
|
1544
|
-
};
|
|
1545
|
-
if (acceptance.level === "none") return ledger;
|
|
1546
|
-
|
|
1547
|
-
if (input.watchdog) {
|
|
1548
|
-
const unresolved = unresolvedChildWatchdogBlockers(input.watchdog);
|
|
1549
|
-
ledger.runtimeChecks.push(unresolved.length
|
|
1550
|
-
? { id: "watchdog-blocker", status: "failed", message: "Unresolved watchdog blocker (details are available in child watchdog status)." }
|
|
1551
|
-
: { id: "watchdog-blocker", status: "passed", message: "No unresolved watchdog blockers." });
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
const parsed: AcceptanceReportParseResult = input.reportError
|
|
1555
|
-
? { error: input.reportError }
|
|
1556
|
-
: input.report !== undefined
|
|
1557
|
-
? (() => {
|
|
1558
|
-
const validation = validateAcceptanceReport(input.report);
|
|
1559
|
-
return validation.report
|
|
1560
|
-
? { report: validation.report }
|
|
1561
|
-
: { error: `Failed to parse acceptance-report: Invalid acceptance-report: ${validation.errors.join("; ")}`, malformed: true };
|
|
1562
|
-
})()
|
|
1563
|
-
: parseAcceptanceReportSources(input.output, input.fileOutput);
|
|
1564
|
-
const durableFileOutput = input.fileOutput?.authoritative && input.fileOutput.durable ? input.fileOutput : undefined;
|
|
1565
|
-
if (parsed.malformed && parsed.sourcePath && durableFileOutput) {
|
|
1566
|
-
ledger.recovery = {
|
|
1567
|
-
status: "available-for-review",
|
|
1568
|
-
reason: "acceptance-metadata-rejected",
|
|
1569
|
-
reportPath: parsed.sourcePath,
|
|
1570
|
-
reportHash: hash(durableFileOutput.content),
|
|
1571
|
-
};
|
|
1572
|
-
}
|
|
1573
|
-
const needsReport = acceptanceRequiresChildReport(acceptance);
|
|
1574
|
-
if (parsed.report) {
|
|
1575
|
-
ledger.childReport = parsed.report;
|
|
1576
|
-
ledger.status = "attested";
|
|
1577
|
-
ledger.evidenceStatus = "attested";
|
|
1578
|
-
} else if (!input.reportOptional || needsReport || parsed.error !== ACCEPTANCE_REPORT_NOT_FOUND) {
|
|
1579
|
-
ledger.childReportParseError = parsed.error;
|
|
1580
|
-
ledger.runtimeChecks.push({ id: "attestation", status: "failed", message: parsed.error ?? "Structured acceptance report missing." });
|
|
1581
|
-
if (ledger.recovery) {
|
|
1582
|
-
ledger.status = "rejected";
|
|
1583
|
-
ledger.evidenceStatus = "rejected";
|
|
1584
|
-
}
|
|
1585
|
-
if (!input.reportOptional) {
|
|
1586
|
-
ledger.status = "rejected";
|
|
1587
|
-
ledger.evidenceStatus = "rejected";
|
|
1588
|
-
return ledger;
|
|
1589
|
-
}
|
|
1590
|
-
} else {
|
|
1591
|
-
ledger.childReportParseError = parsed.error;
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
if (parsed.report && LEVEL_RANK[acceptance.level] >= LEVEL_RANK.checked) {
|
|
1595
|
-
ledger.runtimeChecks = [
|
|
1596
|
-
...ledger.runtimeChecks,
|
|
1597
|
-
...checkCriteriaSatisfied(acceptance.criteria, parsed.report),
|
|
1598
|
-
...runStructuralChecks(acceptance, parsed.report, input.cwd),
|
|
1599
|
-
];
|
|
1600
|
-
if (!ledger.runtimeChecks.some((check) => check.status === "failed")) {
|
|
1601
|
-
ledger.status = "checked";
|
|
1602
|
-
ledger.evidenceStatus = "checked";
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
if (LEVEL_RANK[acceptance.level] >= LEVEL_RANK.verified && (acceptance.level === "verified" || acceptance.verify.length > 0)) {
|
|
1607
|
-
if (acceptance.level === "verified" && acceptance.verify.length === 0) {
|
|
1608
|
-
ledger.runtimeChecks.push({ id: "verification-config", status: "failed", message: "verified acceptance requires runtime verify commands." });
|
|
1609
|
-
ledger.status = "rejected";
|
|
1610
|
-
ledger.evidenceStatus = "rejected";
|
|
1611
|
-
} else {
|
|
1612
|
-
ledger.verifyRuns = [];
|
|
1613
|
-
for (const command of acceptance.verify) {
|
|
1614
|
-
const run = await runMemoizedVerifyCommand(command, input.cwd, {
|
|
1615
|
-
signal: input.signal,
|
|
1616
|
-
abortMessage: input.abortMessage,
|
|
1617
|
-
artifactsDir: input.artifactsDir,
|
|
1618
|
-
runId: input.runId,
|
|
1619
|
-
});
|
|
1620
|
-
if (command.output === "json") await applyTypedVerifyOutput(command, run);
|
|
1621
|
-
ledger.verifyRuns.push(run);
|
|
1622
|
-
if (input.signal?.aborted) break;
|
|
1623
|
-
}
|
|
1624
|
-
if (ledger.verifyRuns.some((run) => run.status === "failed" || run.status === "timed-out")) {
|
|
1625
|
-
ledger.status = "rejected";
|
|
1626
|
-
ledger.evidenceStatus = "rejected";
|
|
1627
|
-
} else if (!ledger.runtimeChecks.some((check) => check.status === "failed")) {
|
|
1628
|
-
ledger.status = "verified";
|
|
1629
|
-
ledger.evidenceStatus = "verified";
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
if (acceptance.preserveStagedIndex) {
|
|
1635
|
-
ledger.runtimeChecks.push(input.stagedIndexBaseline
|
|
1636
|
-
? checkStagedIndexUnchanged(input.cwd, input.stagedIndexBaseline)
|
|
1637
|
-
: { id: "staged-index-unchanged", status: "failed", message: "Staged index launch baseline is unavailable." });
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
if (ledger.status === "rejected" || ledger.runtimeChecks.some((check) => check.status === "failed")) {
|
|
1641
|
-
ledger.status = "rejected";
|
|
1642
|
-
ledger.evidenceStatus = "rejected";
|
|
1643
|
-
return ledger;
|
|
1644
|
-
}
|
|
1645
|
-
if (ledger.status === "claimed") {
|
|
1646
|
-
ledger.status = acceptance.level === "verified" ? "verified" : acceptance.level;
|
|
1647
|
-
ledger.evidenceStatus = ledger.status;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
if (acceptance.review) {
|
|
1651
|
-
if (input.reviewResult?.status === "reviewed") {
|
|
1652
|
-
ledger.reviewResult = input.reviewResult;
|
|
1653
|
-
ledger.status = "reviewed";
|
|
1654
|
-
} else if (input.reviewResult?.status === "blockers") {
|
|
1655
|
-
ledger.reviewResult = input.reviewResult;
|
|
1656
|
-
ledger.status = "rejected";
|
|
1657
|
-
} else if (acceptance.review.required !== false) {
|
|
1658
|
-
ledger.reviewResult = input.reviewResult ?? {
|
|
1659
|
-
status: "review-required",
|
|
1660
|
-
findings: [{
|
|
1661
|
-
severity: "non-blocking",
|
|
1662
|
-
issue: "Independent review has not been supplied.",
|
|
1663
|
-
rationale: "The run cannot be marked reviewed from child evidence alone.",
|
|
1664
|
-
}],
|
|
1665
|
-
};
|
|
1666
|
-
ledger.status = "review-required";
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
return ledger;
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
export function buildSkippedAcceptanceLedger(acceptance: ResolvedAcceptanceConfig, input: { id: string; message: string }): AcceptanceLedger {
|
|
1674
|
-
const status = acceptance.level === "none" ? "not-required" : "rejected";
|
|
1675
|
-
return {
|
|
1676
|
-
status,
|
|
1677
|
-
evidenceStatus: status,
|
|
1678
|
-
explicit: acceptance.explicit,
|
|
1679
|
-
effectiveAcceptance: acceptance,
|
|
1680
|
-
inferredReason: acceptance.inferredReason,
|
|
1681
|
-
criteria: acceptance.criteria,
|
|
1682
|
-
runtimeChecks: acceptance.level === "none"
|
|
1683
|
-
? []
|
|
1684
|
-
: [{ id: input.id, status: "failed", message: input.message }],
|
|
1685
|
-
verifyRuns: [],
|
|
1686
|
-
};
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
export function acceptanceFailureMessage(ledger: AcceptanceLedger): string | undefined {
|
|
1690
|
-
if (ledger.status !== "rejected") return undefined;
|
|
1691
|
-
const failedCheck = ledger.runtimeChecks.find((check) => check.status === "failed");
|
|
1692
|
-
if (failedCheck) return `Acceptance rejected: ${failedCheck.message}`;
|
|
1693
|
-
const failedVerify = ledger.verifyRuns.find((run) => run.status === "failed" || run.status === "timed-out");
|
|
1694
|
-
if (failedVerify?.structuredOutputError) return `Acceptance verification '${failedVerify.id}' failed: ${failedVerify.structuredOutputError}`;
|
|
1695
|
-
if (failedVerify) return `Acceptance verification '${failedVerify.id}' ${failedVerify.status}.`;
|
|
1696
|
-
if (ledger.reviewResult?.status === "blockers") return "Acceptance review found blockers.";
|
|
1697
|
-
return "Acceptance rejected.";
|
|
1698
|
-
}
|