sdd-agent-platform 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -23
- package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js +31 -28
- package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js +3 -2
- package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.d.ts +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js +14 -5
- package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/contracts.d.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/contracts.js +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/contracts.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js +3 -3
- package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js +155 -1
- package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.d.ts +23 -0
- package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js +54 -0
- package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/contracts.d.ts +11 -0
- package/node_modules/@sdd-agent-platform/core/dist/execution/agent-execution-records.js +15 -8
- package/node_modules/@sdd-agent-platform/core/dist/execution/agent-execution-records.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js +14 -6
- package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.d.ts +112 -0
- package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js +145 -0
- package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/instructions.js +36 -36
- package/node_modules/@sdd-agent-platform/core/dist/instructions.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.d.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js +37 -17
- package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.d.ts +16 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js +174 -16
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js +2 -2
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.d.ts +10 -0
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js +31 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.d.ts +2 -17
- package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js +222 -10
- package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js +5 -5
- package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime-config.js +27 -12
- package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime-config.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime.d.ts +59 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.d.ts +3 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js +191 -0
- package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/routing.js +32 -6
- package/node_modules/@sdd-agent-platform/core/dist/router/routing.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/runtime-inspection.js +11 -4
- package/node_modules/@sdd-agent-platform/core/dist/router/runtime-inspection.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js +31 -3
- package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js +48 -15
- package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/events.js +2 -2
- package/node_modules/@sdd-agent-platform/core/dist/run-state/events.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.d.ts +3 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js +15 -49
- package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/invocation-ledger.js +2 -2
- package/node_modules/@sdd-agent-platform/core/dist/run-state/invocation-ledger.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/model.d.ts +25 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js +21 -14
- package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.d.ts +62 -0
- package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js +130 -0
- package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/run-state.d.ts +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/run-state.js +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/run-state.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.d.ts +10 -0
- package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js +44 -14
- package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/context.js +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/context.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.d.ts +4 -0
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js +189 -0
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js +12 -3
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.d.ts +20 -0
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js +101 -21
- package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/status/project-status.d.ts +62 -1
- package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js +192 -4
- package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.d.ts +195 -2
- package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js +499 -2
- package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js +23 -1
- package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.d.ts +19 -0
- package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js +114 -12
- package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js +21 -0
- package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js +16 -2
- package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js +34 -2
- package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js +15 -5
- package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.d.ts +22 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.js +53 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js +102 -9
- package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.d.ts +16 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js +355 -69
- package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.d.ts +58 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js +428 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.d.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js +116 -18
- package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/verification.d.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification.js +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/verification.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.d.ts +24 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js +182 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.d.ts +4 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js +130 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.d.ts +4 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js +146 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.d.ts +89 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.js +2 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js +16 -1
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.d.ts +8 -4
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js +25 -11
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.d.ts +38 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js +122 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js.map +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.d.ts +27 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js +166 -37
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state.d.ts +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state.js +1 -0
- package/node_modules/@sdd-agent-platform/core/dist/workflow-state.js.map +1 -1
- package/node_modules/@sdd-agent-platform/core/package.json +1 -1
- package/node_modules/@sdd-agent-platform/core/src/ai-tools.ts +31 -28
- package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.test.ts +50 -4
- package/node_modules/@sdd-agent-platform/core/src/config/init-project.test.ts +13 -10
- package/node_modules/@sdd-agent-platform/core/src/config/init-project.ts +3 -2
- package/node_modules/@sdd-agent-platform/core/src/config/starter-documents.ts +15 -5
- package/node_modules/@sdd-agent-platform/core/src/contracts.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-evidence.ts +3 -3
- package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.test.ts +117 -5
- package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.ts +164 -1
- package/node_modules/@sdd-agent-platform/core/src/evidence/lookup.ts +80 -0
- package/node_modules/@sdd-agent-platform/core/src/evidence-runtime/contracts.ts +12 -0
- package/node_modules/@sdd-agent-platform/core/src/execution/agent-execution-records.ts +16 -11
- package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.test.ts +7 -0
- package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.test.ts +5 -0
- package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.ts +14 -6
- package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.test.ts +102 -0
- package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.ts +271 -0
- package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.test.ts +4 -0
- package/node_modules/@sdd-agent-platform/core/src/governance/policy.test.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/src/instructions.test.ts +11 -5
- package/node_modules/@sdd-agent-platform/core/src/instructions.ts +36 -36
- package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.ts +39 -17
- package/node_modules/@sdd-agent-platform/core/src/phase8-contracts.test.ts +3 -2
- package/node_modules/@sdd-agent-platform/core/src/phase8-risk-kernel.test.ts +5 -0
- package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.test.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.test.ts +3 -0
- package/node_modules/@sdd-agent-platform/core/src/registries/agent-capability-catalog.ts +269 -17
- package/node_modules/@sdd-agent-platform/core/src/registries/agent-registry.ts +2 -2
- package/node_modules/@sdd-agent-platform/core/src/registries/agent-runtime-static.ts +41 -1
- package/node_modules/@sdd-agent-platform/core/src/registries/capability-sources.ts +238 -15
- package/node_modules/@sdd-agent-platform/core/src/registries/registries.test.ts +27 -2
- package/node_modules/@sdd-agent-platform/core/src/registries/workflow-gates.ts +5 -5
- package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime-config.ts +31 -12
- package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime.ts +66 -1
- package/node_modules/@sdd-agent-platform/core/src/router/route-projection.ts +211 -0
- package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.test.ts +151 -3
- package/node_modules/@sdd-agent-platform/core/src/router/routing.ts +35 -6
- package/node_modules/@sdd-agent-platform/core/src/router/runtime-inspection.ts +11 -4
- package/node_modules/@sdd-agent-platform/core/src/router/runtime-validation.ts +32 -3
- package/node_modules/@sdd-agent-platform/core/src/run-state/artifacts.ts +48 -15
- package/node_modules/@sdd-agent-platform/core/src/run-state/events.ts +2 -2
- package/node_modules/@sdd-agent-platform/core/src/run-state/inspect-run.ts +17 -52
- package/node_modules/@sdd-agent-platform/core/src/run-state/invocation-ledger.ts +2 -2
- package/node_modules/@sdd-agent-platform/core/src/run-state/model.ts +28 -1
- package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.test.ts +3 -0
- package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.ts +22 -18
- package/node_modules/@sdd-agent-platform/core/src/run-state/task-evidence.ts +206 -0
- package/node_modules/@sdd-agent-platform/core/src/run-state.ts +1 -0
- package/node_modules/@sdd-agent-platform/core/src/runtime-paths.ts +54 -14
- package/node_modules/@sdd-agent-platform/core/src/sdd-docs/context.ts +1 -1
- package/node_modules/@sdd-agent-platform/core/src/sdd-docs/document-hashes.ts +207 -0
- package/node_modules/@sdd-agent-platform/core/src/sdd-docs/run-binding.ts +12 -3
- package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.test.ts +139 -0
- package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.ts +137 -24
- package/node_modules/@sdd-agent-platform/core/src/status/project-status.ts +268 -5
- package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.test.ts +368 -4
- package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.ts +697 -2
- package/node_modules/@sdd-agent-platform/core/src/sync-back/apply.ts +23 -1
- package/node_modules/@sdd-agent-platform/core/src/sync-back/inspect.ts +145 -12
- package/node_modules/@sdd-agent-platform/core/src/sync-back/sync-back.test.ts +132 -9
- package/node_modules/@sdd-agent-platform/core/src/test-support/fixtures.ts +21 -0
- package/node_modules/@sdd-agent-platform/core/src/test-support/run-state.ts +16 -2
- package/node_modules/@sdd-agent-platform/core/src/verification/goal-verify.test.ts +1 -1
- package/node_modules/@sdd-agent-platform/core/src/verification/goal-verify.ts +38 -5
- package/node_modules/@sdd-agent-platform/core/src/verification/rendering.ts +15 -5
- package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.test.ts +77 -0
- package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.ts +77 -0
- package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.test.ts +64 -4
- package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.ts +110 -12
- package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.test.ts +72 -25
- package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.ts +402 -77
- package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.test.ts +341 -0
- package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.ts +513 -0
- package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.test.ts +144 -5
- package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.ts +129 -18
- package/node_modules/@sdd-agent-platform/core/src/verification.ts +2 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/evidence-packet.ts +196 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.test.ts +171 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.ts +143 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.test.ts +137 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.ts +155 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-gate/types.ts +114 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/affected-file-conflicts.ts +18 -1
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.test.ts +1 -1
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.ts +33 -11
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/latest-eligible-run.ts +156 -0
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.test.ts +351 -2
- package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.ts +227 -39
- package/node_modules/@sdd-agent-platform/core/src/workflow-state.ts +1 -0
- package/package.json +1 -1
- package/packages/cli/dist/commands/status.js +2 -2
- package/packages/cli/dist/commands/status.js.map +1 -1
- package/packages/cli/dist/commands/sync-back.js +1 -1
- package/packages/cli/dist/commands/sync-back.js.map +1 -1
- package/packages/cli/dist/commands/tasks.js +4 -4
- package/packages/cli/dist/commands/tasks.js.map +1 -1
- package/packages/cli/dist/commands/test.js +94 -5
- package/packages/cli/dist/commands/test.js.map +1 -1
- package/packages/cli/dist/commands/verifies.js +5 -3
- package/packages/cli/dist/commands/verifies.js.map +1 -1
- package/packages/cli/dist/commands/verify.js +48 -7
- package/packages/cli/dist/commands/verify.js.map +1 -1
- package/packages/cli/dist/help.js +32 -18
- package/packages/cli/dist/help.js.map +1 -1
- package/packages/cli/dist/renderers/artifacts.js +1 -1
- package/packages/cli/dist/renderers/artifacts.js.map +1 -1
- package/packages/cli/dist/renderers/registry-runtime.js +7 -2
- package/packages/cli/dist/renderers/registry-runtime.js.map +1 -1
- package/packages/cli/dist/renderers/router.js +4 -2
- package/packages/cli/dist/renderers/router.js.map +1 -1
- package/packages/cli/dist/renderers/workflow.js +33 -12
- package/packages/cli/dist/renderers/workflow.js.map +1 -1
- package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/cli/package.json +2 -2
- package/packages/core/dist/ai-tools.js +31 -28
- package/packages/core/dist/ai-tools.js.map +1 -1
- package/packages/core/dist/config/init-project.js +3 -2
- package/packages/core/dist/config/init-project.js.map +1 -1
- package/packages/core/dist/config/starter-documents.d.ts +1 -1
- package/packages/core/dist/config/starter-documents.js +14 -5
- package/packages/core/dist/config/starter-documents.js.map +1 -1
- package/packages/core/dist/contracts.d.ts +2 -0
- package/packages/core/dist/contracts.js +2 -0
- package/packages/core/dist/contracts.js.map +1 -1
- package/packages/core/dist/doctor/checks/run-evidence.js +3 -3
- package/packages/core/dist/doctor/checks/run-evidence.js.map +1 -1
- package/packages/core/dist/doctor/doctor.js +155 -1
- package/packages/core/dist/doctor/doctor.js.map +1 -1
- package/packages/core/dist/evidence/lookup.d.ts +23 -0
- package/packages/core/dist/evidence/lookup.js +54 -0
- package/packages/core/dist/evidence/lookup.js.map +1 -0
- package/packages/core/dist/evidence-runtime/contracts.d.ts +11 -0
- package/packages/core/dist/execution/agent-execution-records.js +15 -8
- package/packages/core/dist/execution/agent-execution-records.js.map +1 -1
- package/packages/core/dist/execution/resident-worker.js +14 -6
- package/packages/core/dist/execution/resident-worker.js.map +1 -1
- package/packages/core/dist/execution/stage-team-runtime.d.ts +112 -0
- package/packages/core/dist/execution/stage-team-runtime.js +145 -0
- package/packages/core/dist/execution/stage-team-runtime.js.map +1 -0
- package/packages/core/dist/instructions.js +36 -36
- package/packages/core/dist/instructions.js.map +1 -1
- package/packages/core/dist/lifecycle/ship.d.ts +2 -0
- package/packages/core/dist/lifecycle/ship.js +37 -17
- package/packages/core/dist/lifecycle/ship.js.map +1 -1
- package/packages/core/dist/registries/agent-capability-catalog.d.ts +16 -1
- package/packages/core/dist/registries/agent-capability-catalog.js +174 -16
- package/packages/core/dist/registries/agent-capability-catalog.js.map +1 -1
- package/packages/core/dist/registries/agent-registry.js +2 -2
- package/packages/core/dist/registries/agent-registry.js.map +1 -1
- package/packages/core/dist/registries/agent-runtime-static.d.ts +10 -0
- package/packages/core/dist/registries/agent-runtime-static.js +31 -1
- package/packages/core/dist/registries/agent-runtime-static.js.map +1 -1
- package/packages/core/dist/registries/capability-sources.d.ts +2 -17
- package/packages/core/dist/registries/capability-sources.js +222 -10
- package/packages/core/dist/registries/capability-sources.js.map +1 -1
- package/packages/core/dist/registries/workflow-gates.js +5 -5
- package/packages/core/dist/registries/workflow-gates.js.map +1 -1
- package/packages/core/dist/router/agent-runtime-config.js +27 -12
- package/packages/core/dist/router/agent-runtime-config.js.map +1 -1
- package/packages/core/dist/router/agent-runtime.d.ts +59 -1
- package/packages/core/dist/router/route-projection.d.ts +3 -1
- package/packages/core/dist/router/route-projection.js +191 -0
- package/packages/core/dist/router/route-projection.js.map +1 -1
- package/packages/core/dist/router/routing.js +32 -6
- package/packages/core/dist/router/routing.js.map +1 -1
- package/packages/core/dist/router/runtime-inspection.js +11 -4
- package/packages/core/dist/router/runtime-inspection.js.map +1 -1
- package/packages/core/dist/router/runtime-validation.js +31 -3
- package/packages/core/dist/router/runtime-validation.js.map +1 -1
- package/packages/core/dist/run-state/artifacts.js +48 -15
- package/packages/core/dist/run-state/artifacts.js.map +1 -1
- package/packages/core/dist/run-state/events.js +2 -2
- package/packages/core/dist/run-state/events.js.map +1 -1
- package/packages/core/dist/run-state/inspect-run.d.ts +3 -1
- package/packages/core/dist/run-state/inspect-run.js +15 -49
- package/packages/core/dist/run-state/inspect-run.js.map +1 -1
- package/packages/core/dist/run-state/invocation-ledger.js +2 -2
- package/packages/core/dist/run-state/invocation-ledger.js.map +1 -1
- package/packages/core/dist/run-state/model.d.ts +25 -1
- package/packages/core/dist/run-state/run-state.js +21 -14
- package/packages/core/dist/run-state/run-state.js.map +1 -1
- package/packages/core/dist/run-state/task-evidence.d.ts +62 -0
- package/packages/core/dist/run-state/task-evidence.js +130 -0
- package/packages/core/dist/run-state/task-evidence.js.map +1 -0
- package/packages/core/dist/run-state.d.ts +1 -0
- package/packages/core/dist/run-state.js +1 -0
- package/packages/core/dist/run-state.js.map +1 -1
- package/packages/core/dist/runtime-paths.d.ts +10 -0
- package/packages/core/dist/runtime-paths.js +44 -14
- package/packages/core/dist/runtime-paths.js.map +1 -1
- package/packages/core/dist/sdd-docs/context.js +1 -1
- package/packages/core/dist/sdd-docs/context.js.map +1 -1
- package/packages/core/dist/sdd-docs/document-hashes.d.ts +4 -0
- package/packages/core/dist/sdd-docs/document-hashes.js +189 -0
- package/packages/core/dist/sdd-docs/document-hashes.js.map +1 -0
- package/packages/core/dist/sdd-docs/run-binding.js +12 -3
- package/packages/core/dist/sdd-docs/run-binding.js.map +1 -1
- package/packages/core/dist/sdd-docs/task-parser.d.ts +20 -0
- package/packages/core/dist/sdd-docs/task-parser.js +101 -21
- package/packages/core/dist/sdd-docs/task-parser.js.map +1 -1
- package/packages/core/dist/status/project-status.d.ts +62 -1
- package/packages/core/dist/status/project-status.js +192 -4
- package/packages/core/dist/status/project-status.js.map +1 -1
- package/packages/core/dist/storage/runtime-store.d.ts +195 -2
- package/packages/core/dist/storage/runtime-store.js +499 -2
- package/packages/core/dist/storage/runtime-store.js.map +1 -1
- package/packages/core/dist/sync-back/apply.js +23 -1
- package/packages/core/dist/sync-back/apply.js.map +1 -1
- package/packages/core/dist/sync-back/inspect.d.ts +19 -0
- package/packages/core/dist/sync-back/inspect.js +114 -12
- package/packages/core/dist/sync-back/inspect.js.map +1 -1
- package/packages/core/dist/test-support/fixtures.js +21 -0
- package/packages/core/dist/test-support/fixtures.js.map +1 -1
- package/packages/core/dist/test-support/run-state.js +16 -2
- package/packages/core/dist/test-support/run-state.js.map +1 -1
- package/packages/core/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/core/dist/verification/goal-verify.js +34 -2
- package/packages/core/dist/verification/goal-verify.js.map +1 -1
- package/packages/core/dist/verification/rendering.js +15 -5
- package/packages/core/dist/verification/rendering.js.map +1 -1
- package/packages/core/dist/verification/review-gate.d.ts +22 -0
- package/packages/core/dist/verification/review-gate.js +53 -0
- package/packages/core/dist/verification/review-gate.js.map +1 -0
- package/packages/core/dist/verification/single-task-loop.js +102 -9
- package/packages/core/dist/verification/single-task-loop.js.map +1 -1
- package/packages/core/dist/verification/test-runtime.d.ts +16 -1
- package/packages/core/dist/verification/test-runtime.js +355 -69
- package/packages/core/dist/verification/test-runtime.js.map +1 -1
- package/packages/core/dist/verification/validation-wave.d.ts +58 -0
- package/packages/core/dist/verification/validation-wave.js +428 -0
- package/packages/core/dist/verification/validation-wave.js.map +1 -0
- package/packages/core/dist/verification/verify-contract.d.ts +2 -0
- package/packages/core/dist/verification/verify-contract.js +116 -18
- package/packages/core/dist/verification/verify-contract.js.map +1 -1
- package/packages/core/dist/verification.d.ts +2 -0
- package/packages/core/dist/verification.js +2 -0
- package/packages/core/dist/verification.js.map +1 -1
- package/packages/core/dist/workflow-gate/evidence-packet.d.ts +24 -0
- package/packages/core/dist/workflow-gate/evidence-packet.js +182 -0
- package/packages/core/dist/workflow-gate/evidence-packet.js.map +1 -0
- package/packages/core/dist/workflow-gate/hard-checks.d.ts +4 -0
- package/packages/core/dist/workflow-gate/hard-checks.js +130 -0
- package/packages/core/dist/workflow-gate/hard-checks.js.map +1 -0
- package/packages/core/dist/workflow-gate/policy.d.ts +4 -0
- package/packages/core/dist/workflow-gate/policy.js +146 -0
- package/packages/core/dist/workflow-gate/policy.js.map +1 -0
- package/packages/core/dist/workflow-gate/types.d.ts +89 -0
- package/packages/core/dist/workflow-gate/types.js +2 -0
- package/packages/core/dist/workflow-gate/types.js.map +1 -0
- package/packages/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
- package/packages/core/dist/workflow-state/affected-file-conflicts.js +16 -1
- package/packages/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
- package/packages/core/dist/workflow-state/dependencies.d.ts +8 -4
- package/packages/core/dist/workflow-state/dependencies.js +25 -11
- package/packages/core/dist/workflow-state/dependencies.js.map +1 -1
- package/packages/core/dist/workflow-state/latest-eligible-run.d.ts +38 -0
- package/packages/core/dist/workflow-state/latest-eligible-run.js +122 -0
- package/packages/core/dist/workflow-state/latest-eligible-run.js.map +1 -0
- package/packages/core/dist/workflow-state/resolve.d.ts +27 -0
- package/packages/core/dist/workflow-state/resolve.js +166 -37
- package/packages/core/dist/workflow-state/resolve.js.map +1 -1
- package/packages/core/dist/workflow-state.d.ts +1 -0
- package/packages/core/dist/workflow-state.js +1 -0
- package/packages/core/dist/workflow-state.js.map +1 -1
- package/packages/core/package.json +1 -1
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import type { AgentCapabilityCatalog, AgentCapabilityCatalogEntry, AgentCapabilityDomain, AgentCapabilityMaterialPack, AgentCapabilityStage } from '../registries/agent-capability-catalog.js';
|
|
1
2
|
import { TOOL_PERMISSION_SPEC_VERSION } from '../contracts.js';
|
|
2
3
|
import type { LifecycleAutonomyCeiling } from '../lifecycle/decision-gate.js';
|
|
3
4
|
import type { SddTask, SddTaskGap } from '../sdd-docs/task-parser.js';
|
|
4
5
|
import type {
|
|
6
|
+
AgentCapabilityRouteDecision,
|
|
5
7
|
AgentProfileId,
|
|
6
8
|
AgentRouterCategory,
|
|
7
9
|
AgentRouterRejectedProfile,
|
|
8
10
|
AgentRuntimeAdapterMapping,
|
|
9
11
|
AgentRuntimeRoutingRule,
|
|
12
|
+
CapabilitySourceCatalogEntry,
|
|
10
13
|
ModelPolicyContract,
|
|
11
14
|
RuntimeRegistryEntrySource,
|
|
12
15
|
ToolPermissionSpec
|
|
@@ -79,6 +82,56 @@ export function selectRequiredSkillCapabilities(task: SddTask, profile: AgentPro
|
|
|
79
82
|
return [...capabilities];
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
export function buildAgentCapabilityRouteDecision(task: SddTask | null, category: AgentRouterCategory, autonomyCeiling: LifecycleAutonomyCeiling, registry: AgentSkillRuntimeRegistry, catalog: AgentCapabilityCatalog): AgentCapabilityRouteDecision {
|
|
86
|
+
if (!task) {
|
|
87
|
+
return {
|
|
88
|
+
authority: 'advisory_only',
|
|
89
|
+
selectedDomains: [],
|
|
90
|
+
selectedPacks: [],
|
|
91
|
+
rejectedExternalSources: rejectedCapabilitySources(registry.capabilitySources),
|
|
92
|
+
consideredExternalSources: consideredCapabilitySources(registry.capabilitySources),
|
|
93
|
+
evidenceRequirements: ['task metadata must exist before capability routing can select evidence requirements'],
|
|
94
|
+
permissionCeiling: autonomyCeiling
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const stage = routeCapabilityStage(task, category);
|
|
98
|
+
const text = taskSignalText(task);
|
|
99
|
+
const selectedCapabilities = catalog.capabilities.filter((capability) => capability.domainGroup === 'professional' && capabilityStageFits(capability, stage, task, text) && capabilityMatchesTask(capability, task, text));
|
|
100
|
+
const effectiveCapabilities = selectedCapabilities.length > 0 ? selectedCapabilities : fallbackCapabilitiesForTask(catalog.capabilities, task, stage);
|
|
101
|
+
const packById = new Map(catalog.materialPacks.map((pack) => [pack.id, pack]));
|
|
102
|
+
const selectedPackIds = new Set<string>();
|
|
103
|
+
for (const capability of effectiveCapabilities) {
|
|
104
|
+
for (const packId of capability.routing.materialPackIds) {
|
|
105
|
+
const pack = packById.get(packId);
|
|
106
|
+
if (pack && pack.loadPolicy !== 'never_inline' && packFitsRoute(pack, stage, text)) {
|
|
107
|
+
selectedPackIds.add(packId);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
authority: 'advisory_only',
|
|
113
|
+
selectedDomains: effectiveCapabilities.map((capability) => ({
|
|
114
|
+
domain: capability.domain,
|
|
115
|
+
capabilityId: capability.id,
|
|
116
|
+
authority: capability.authority,
|
|
117
|
+
reason: capabilityReason(capability, task)
|
|
118
|
+
})),
|
|
119
|
+
selectedPacks: [...selectedPackIds].map((packId) => packById.get(packId)).filter((pack): pack is AgentCapabilityMaterialPack => Boolean(pack)).map((pack) => ({
|
|
120
|
+
id: pack.id,
|
|
121
|
+
domains: [...pack.domains],
|
|
122
|
+
loadPolicy: pack.loadPolicy,
|
|
123
|
+
contextBudget: pack.contextBudget,
|
|
124
|
+
sourceKind: pack.sourceKind,
|
|
125
|
+
expectedOutputs: [...pack.expectedOutputs],
|
|
126
|
+
reason: packReason(pack, stage)
|
|
127
|
+
})),
|
|
128
|
+
rejectedExternalSources: rejectedCapabilitySources(registry.capabilitySources),
|
|
129
|
+
consideredExternalSources: consideredCapabilitySources(registry.capabilitySources),
|
|
130
|
+
evidenceRequirements: evidenceRequirementsForCapabilities(effectiveCapabilities),
|
|
131
|
+
permissionCeiling: autonomyCeiling
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
82
135
|
export function routeRegistrySources(registry: AgentSkillRuntimeRegistry, profile: AgentProfileId | null, capabilityIds: string[]): RuntimeRegistryEntrySource[] {
|
|
83
136
|
const selected: RuntimeRegistryEntrySource[] = [];
|
|
84
137
|
const seen = new Set<string>();
|
|
@@ -144,3 +197,161 @@ export function buildRejectedProfiles(allowedProfiles: AgentProfileId[], blocked
|
|
|
144
197
|
.filter((profile) => !allowed.has(profile.id))
|
|
145
198
|
.map((profile) => ({ profile: profile.id, reason: blockedReason ?? 'Profile is outside task metadata allowed_agents/agent_fit, routing rules, or router risk category.' }));
|
|
146
199
|
}
|
|
200
|
+
|
|
201
|
+
function routeCapabilityStage(task: SddTask, category: AgentRouterCategory): AgentCapabilityStage {
|
|
202
|
+
if (category === 'planning') {
|
|
203
|
+
return 'plan';
|
|
204
|
+
}
|
|
205
|
+
if (category === 'validation' || task.status === 'completed') {
|
|
206
|
+
return 'test';
|
|
207
|
+
}
|
|
208
|
+
return 'do';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function taskSignalText(task: SddTask): string {
|
|
212
|
+
return [
|
|
213
|
+
task.id,
|
|
214
|
+
task.title ?? '',
|
|
215
|
+
task.boundary ?? '',
|
|
216
|
+
task.implementationNotes ?? '',
|
|
217
|
+
...task.risk,
|
|
218
|
+
...task.affectedFiles,
|
|
219
|
+
...task.validation,
|
|
220
|
+
...task.acceptance,
|
|
221
|
+
...task.allowedAgents,
|
|
222
|
+
...task.agentFit
|
|
223
|
+
].join('\n').toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function capabilityMatchesTask(capability: AgentCapabilityCatalogEntry, task: SddTask, text: string): boolean {
|
|
227
|
+
return capability.routing.riskTags.some((tag) => text.includes(tag.toLowerCase())) || capability.routing.projectStackTags.some((tag) => projectStackMatches(tag, task, text)) || capability.routing.materialPackIds.some((packId) => text.includes(packId.replace(/^baseline-/, '').replace(/-/g, ' '))) || domainFileSignal(capability.domain, task.affectedFiles);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function fallbackCapabilitiesForTask(capabilities: AgentCapabilityCatalogEntry[], task: SddTask, stage: AgentCapabilityStage): AgentCapabilityCatalogEntry[] {
|
|
231
|
+
const codeFile = task.affectedFiles.some((file) => /\.(ts|js|java|go|py|rs|cs|php|rb)$/i.test(file));
|
|
232
|
+
const fallbackDomain: AgentCapabilityDomain = codeFile ? 'backend-engineering' : 'solution-design';
|
|
233
|
+
const fallback = capabilities.find((capability) => capability.domain === fallbackDomain && capabilityStageFits(capability, stage, task, taskSignalText(task)));
|
|
234
|
+
return fallback ? [fallback] : [];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function packFitsRoute(pack: AgentCapabilityMaterialPack, stage: AgentCapabilityStage, text: string): boolean {
|
|
238
|
+
const keywordTriggered = pack.triggerKeywords.some((keyword) => text.includes(keyword.toLowerCase()));
|
|
239
|
+
if (pack.sourceKind === 'sdd_native_baseline') {
|
|
240
|
+
return pack.triggerStages.includes(stage) || keywordTriggered;
|
|
241
|
+
}
|
|
242
|
+
return pack.triggerStages.includes(stage) && keywordTriggered;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function domainFileSignal(domain: AgentCapabilityDomain, affectedFiles: string[]): boolean {
|
|
246
|
+
const files = affectedFiles.map((file) => file.toLowerCase());
|
|
247
|
+
if (domain === 'frontend-engineering') {
|
|
248
|
+
return files.some((file) => /\.(tsx|jsx|vue|svelte|css|scss|less)$/.test(file) || file.includes('/components/') || file.includes('/pages/'));
|
|
249
|
+
}
|
|
250
|
+
if (domain === 'db-data-engineering') {
|
|
251
|
+
return files.some((file) => /\.(sql|prisma)$/.test(file) || file.includes('migration') || file.includes('schema') || file.includes('database'));
|
|
252
|
+
}
|
|
253
|
+
if (domain === 'backend-engineering') {
|
|
254
|
+
return files.some((file) => /\.(ts|js|java|go|py|rs|cs|php|rb)$/.test(file)) && !domainFileSignal('frontend-engineering', affectedFiles);
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function capabilityStageFits(capability: AgentCapabilityCatalogEntry, stage: AgentCapabilityStage, task: SddTask, text: string): boolean {
|
|
260
|
+
if (capability.stages.includes(stage)) {
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
if (capability.domain === 'testing-quality-engineering' && stage === 'do') {
|
|
264
|
+
return testingQualityTaskSignal(task);
|
|
265
|
+
}
|
|
266
|
+
return capability.domain === 'release-engineering' && /release|ship|deploy|rollback|ci|发布/.test(text);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function testingQualityTaskSignal(task: SddTask): boolean {
|
|
270
|
+
const taskText = [task.id, task.title ?? '', task.boundary ?? '', task.implementationNotes ?? '', ...task.risk, ...task.affectedFiles, ...task.acceptance].join('\n').toLowerCase();
|
|
271
|
+
return /quality|coverage|acceptance|验证|测试/.test(taskText) || task.affectedFiles.some((file) => /\.(test|spec)\.[tj]sx?$/i.test(file));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function capabilityReason(capability: AgentCapabilityCatalogEntry, task: SddTask): string {
|
|
275
|
+
const fileSignal = domainFileSignal(capability.domain, task.affectedFiles) ? 'affected file evidence' : 'task risk, validation, or text evidence';
|
|
276
|
+
return `${capability.domain} selected from ${fileSignal}; authority remains ${capability.authority}.`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function packReason(pack: AgentCapabilityMaterialPack, stage: AgentCapabilityStage): string {
|
|
280
|
+
return `${pack.id} is route_when_triggered for ${stage} and stays ${pack.contextBudget} context.`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function evidenceRequirementsForCapabilities(capabilities: AgentCapabilityCatalogEntry[]): string[] {
|
|
284
|
+
const requirements = new Set<string>();
|
|
285
|
+
for (const capability of capabilities) {
|
|
286
|
+
for (const output of capability.outputs) {
|
|
287
|
+
requirements.add(`${capability.domain}: ${output}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return [...requirements];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function consideredCapabilitySources(sources: CapabilitySourceCatalogEntry[]): AgentCapabilityRouteDecision['consideredExternalSources'] {
|
|
294
|
+
return sources
|
|
295
|
+
.filter((source) => source.kind !== 'native_host')
|
|
296
|
+
.map((source) => ({
|
|
297
|
+
sourceId: source.id,
|
|
298
|
+
kind: source.kind,
|
|
299
|
+
quarantineStatus: source.quarantineStatus,
|
|
300
|
+
reuseDecision: source.reuseDecision,
|
|
301
|
+
allowedEvidenceTypes: [...source.allowedEvidenceTypes],
|
|
302
|
+
consideredUse: source.allowedUse,
|
|
303
|
+
reason: rejectedSourceReason(source)
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
function rejectedCapabilitySources(sources: CapabilitySourceCatalogEntry[]): AgentCapabilityRouteDecision['rejectedExternalSources'] {
|
|
309
|
+
return sources
|
|
310
|
+
.filter((source) => source.kind !== 'native_host' && (source.quarantineRequired || source.reuseDecision !== 'reuse_direct' || source.kind === 'future_adapter'))
|
|
311
|
+
.map((source) => ({
|
|
312
|
+
sourceId: source.id,
|
|
313
|
+
quarantineStatus: source.quarantineStatus,
|
|
314
|
+
reuseDecision: source.reuseDecision,
|
|
315
|
+
allowedEvidenceTypes: [...source.allowedEvidenceTypes],
|
|
316
|
+
reason: rejectedSourceReason(source)
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function projectStackMatches(tag: string, task: SddTask, text: string): boolean {
|
|
321
|
+
if (tag === 'generic') {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
if (text.includes(tag.toLowerCase())) {
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
const files = task.affectedFiles.map((file) => file.toLowerCase());
|
|
328
|
+
if (tag === 'typescript') {
|
|
329
|
+
return files.some((file) => /\.(ts|tsx)$/.test(file));
|
|
330
|
+
}
|
|
331
|
+
if (tag === 'javascript') {
|
|
332
|
+
return files.some((file) => /\.(js|jsx)$/.test(file));
|
|
333
|
+
}
|
|
334
|
+
if (tag === 'java') {
|
|
335
|
+
return files.some((file) => file.endsWith('.java'));
|
|
336
|
+
}
|
|
337
|
+
if (tag === 'sql') {
|
|
338
|
+
return files.some((file) => /\.(sql|prisma)$/.test(file));
|
|
339
|
+
}
|
|
340
|
+
return files.some((file) => file.includes(tag.toLowerCase()));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function rejectedSourceReason(source: CapabilitySourceCatalogEntry): string {
|
|
344
|
+
if (source.quarantineStatus === 'denied') {
|
|
345
|
+
return 'Source is denied or unsupported and cannot participate in routing.';
|
|
346
|
+
}
|
|
347
|
+
if (source.kind === 'future_adapter') {
|
|
348
|
+
return 'Future adapter is recorded as metadata only until host behavior is validated.';
|
|
349
|
+
}
|
|
350
|
+
if (source.quarantineStatus === 'quarantined' || source.quarantineStatus === 'required') {
|
|
351
|
+
return 'Source requires quarantine/provenance review and is not invoked by capability routing.';
|
|
352
|
+
}
|
|
353
|
+
if (source.reuseDecision === 'avoid') {
|
|
354
|
+
return 'Reuse policy avoids this source.';
|
|
355
|
+
}
|
|
356
|
+
return 'External source is considered but not loaded during progressive disclosure.';
|
|
357
|
+
}
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
validTaskMarkdown,
|
|
15
15
|
writeBranchDocs
|
|
16
16
|
} from '../test-support/fixtures.js';
|
|
17
|
+
import { writeVerifyContract } from '../verification/verify-contract.js';
|
|
18
|
+
import { createRun, readRunState, writeRunState } from '../run-state/run-state.js';
|
|
19
|
+
import { bindTestRunState } from '../test-support/run-state.js';
|
|
17
20
|
import {
|
|
18
21
|
inspectAgentSkillTeamRuntime,
|
|
19
22
|
inspectCapabilitySource,
|
|
@@ -38,12 +41,18 @@ test('Phase 6 agent skill team runtime exposes reusable contracts and router dec
|
|
|
38
41
|
const sourceCatalog = await listCapabilitySources(root);
|
|
39
42
|
const agencySource = await inspectCapabilitySource(root, 'agency_agents_material');
|
|
40
43
|
const agencyImport = await inspectExternalAgentPackImport(root, 'agency_agents_material');
|
|
44
|
+
const codexSource = await inspectCapabilitySource(root, 'codex_host_future');
|
|
45
|
+
const codexImport = await inspectExternalAgentPackImport(root, 'codex_host_future');
|
|
46
|
+
const figmaSource = await inspectCapabilitySource(root, 'figma_design_future');
|
|
41
47
|
const teamDefault = await inspectTeamModePolicy(root);
|
|
42
48
|
const teamEnabled = await inspectTeamModePolicy(root, { taskId: 'ONBOARDING-1', branch: 'master', enabled: true });
|
|
43
49
|
const route = await routeSddTask(root, { taskId: 'ONBOARDING-1', branch: 'master', teamModeEnabled: true });
|
|
44
50
|
|
|
45
51
|
assert.equal(runtime.version, 'phase-6.0-agent-skill-team-runtime-v1');
|
|
46
52
|
assert.equal(runtime.teamMode.decision, 'disabled');
|
|
53
|
+
assert.equal(runtime.hostAdapter.workflowProjectionPolicy.includes('host-neutral canonical CLI commands'), true);
|
|
54
|
+
assert.deepEqual(runtime.hostAdapter.workflowProjections.map((projection) => `${projection.host}:${projection.support}`), ['claude_code:active', 'codex:future', 'opencode:active']);
|
|
55
|
+
assert.equal(runtime.hostAdapter.workflowProjections.find((projection) => projection.host === 'codex')?.unsupportedReason?.includes('not marked active'), true);
|
|
47
56
|
assert.equal(runtime.profiles.some((profile) => profile.id === 'orchestrator'), true);
|
|
48
57
|
assert.equal(runtime.profiles.some((profile) => profile.id === 'security'), true);
|
|
49
58
|
assert.equal(runtime.skillCapabilities.some((capability) => capability.id === 'claude.subagent.researcher'), true);
|
|
@@ -52,8 +61,19 @@ test('Phase 6 agent skill team runtime exposes reusable contracts and router dec
|
|
|
52
61
|
assert.ok(hashlineCapability);
|
|
53
62
|
assert.equal(hashlineCapability.reuseDecision, 'reuse_direct');
|
|
54
63
|
assert.equal(sourceCatalog.sources.some((source) => source.id === 'ohmy_team_mode'), true);
|
|
64
|
+
assert.ok(codexSource);
|
|
65
|
+
assert.equal(codexSource.quarantineStatus, 'denied');
|
|
66
|
+
assert.equal(codexSource.hostCompatibility.includes('codex:unsupported'), true);
|
|
67
|
+
assert.equal(codexImport.status, 'denied');
|
|
68
|
+
assert.equal(codexImport.allowedProfiles.length, 0);
|
|
69
|
+
assert.ok(figmaSource);
|
|
70
|
+
assert.equal(figmaSource.allowedEvidenceTypes.includes('design_context'), true);
|
|
71
|
+
assert.equal(figmaSource.reuseDecision, 'adapt_via_host_adapter');
|
|
55
72
|
assert.ok(agencySource);
|
|
56
73
|
assert.equal(agencySource.quarantineRequired, true);
|
|
74
|
+
assert.equal(agencySource.quarantineStatus, 'quarantined');
|
|
75
|
+
assert.equal(agencySource.permissionModel.length > 0, true);
|
|
76
|
+
assert.equal(agencySource.provenanceRequirements.length > 0, true);
|
|
57
77
|
assert.equal(agencyImport.status, 'quarantined');
|
|
58
78
|
assert.equal(agencyImport.checks.some((check) => check.check === 'dangerous_command_scan'), true);
|
|
59
79
|
assert.equal(teamDefault.decision, 'disabled');
|
|
@@ -80,6 +100,7 @@ test('Phase 6 adaptive team-mode routes choose cost-bounded agent teams automati
|
|
|
80
100
|
try {
|
|
81
101
|
await initProject(root);
|
|
82
102
|
await writeBranchDocs(root, 'master', `# Tasks\n\n${adaptiveTeamTaskMarkdown('LOW', { allowedAgents: ['implementer'], affectedFiles: ['docs/low.md'] })}\n${adaptiveTeamTaskMarkdown('REVIEW', { allowedAgents: ['reviewer'], requiredArtifacts: ['artifacts/review-REVIEW.md'], affectedFiles: ['docs/review.md'] })}\n${adaptiveTeamTaskMarkdown('SOURCE', { allowedAgents: ['implementer'] })}\n${adaptiveTeamTaskMarkdown('HIGH', { allowedAgents: ['implementer'], risk: ['database'] })}\n${adaptiveTeamTaskMarkdown('SECURITY', { allowedAgents: ['security'], risk: ['security'] })}`);
|
|
103
|
+
await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
|
|
83
104
|
|
|
84
105
|
const low = await routeSddTask(root, { taskId: 'LOW', branch: 'master' });
|
|
85
106
|
const review = await routeSddTask(root, { taskId: 'REVIEW', branch: 'master' });
|
|
@@ -156,6 +177,7 @@ test('routeSddTask uses derived route cache and opt-in profiling only', async ()
|
|
|
156
177
|
try {
|
|
157
178
|
await initProject(root);
|
|
158
179
|
await writeBranchDocs(root, 'master', `# Tasks\n\n${adaptiveTeamTaskMarkdown('CACHE', { allowedAgents: ['reviewer'], requiredArtifacts: ['artifacts/review-CACHE.md'], affectedFiles: ['docs/cache.md'] })}`);
|
|
180
|
+
await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
|
|
159
181
|
|
|
160
182
|
const uncached = await routeSddTask(root, { taskId: 'CACHE', branch: 'master' });
|
|
161
183
|
const first = await routeSddTask(root, { taskId: 'CACHE', branch: 'master', cache: true, profile: true });
|
|
@@ -181,6 +203,7 @@ test('routeSddTask uses derived route cache and opt-in profiling only', async ()
|
|
|
181
203
|
assert.equal(third.profile.some((span) => span.name === 'route_compute'), false);
|
|
182
204
|
|
|
183
205
|
await writeBranchDocs(root, 'master', `# Tasks\n\n${adaptiveTeamTaskMarkdown('CACHE', { allowedAgents: ['reviewer'], requiredArtifacts: ['artifacts/review-CACHE.md'], affectedFiles: ['docs/cache.md'] })}\n\nCache key invalidation fixture.`);
|
|
206
|
+
await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
|
|
184
207
|
const invalidated = await routeSddTask(root, { taskId: 'CACHE', branch: 'master', cache: true });
|
|
185
208
|
|
|
186
209
|
assert.equal(invalidated.cache?.status, 'stored');
|
|
@@ -197,6 +220,7 @@ test('Phase 6.3 project agent runtime merges project config and routes by alias
|
|
|
197
220
|
await initProject(root);
|
|
198
221
|
await appendProjectRuntimeConfig(root, phase63ProjectRuntimeConfig());
|
|
199
222
|
await writeBranchDocs(root, 'master', phase63FrontendTaskMarkdown('FRONTEND-1'));
|
|
223
|
+
await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
|
|
200
224
|
|
|
201
225
|
const runtime = await inspectAgentSkillTeamRuntime(root);
|
|
202
226
|
const validation = await validateAgentSkillTeamRuntime(root);
|
|
@@ -249,6 +273,12 @@ test('Phase 6.3 invalid agent runtime declarations fail closed', async () => {
|
|
|
249
273
|
assert.match(issueText, /project\.skill\.bad\.evidenceType/);
|
|
250
274
|
assert.match(issueText, /unknown source missing_source/);
|
|
251
275
|
assert.match(issueText, /unsafe_source\.attribution/);
|
|
276
|
+
assert.match(issueText, /unsafe_source\.permissionModel/);
|
|
277
|
+
assert.match(issueText, /unsafe_source\.provenanceRequirements/);
|
|
278
|
+
assert.match(issueText, /unsafe_source\.hostCompatibility/);
|
|
279
|
+
assert.match(issueText, /unsafe_source\.allowedEvidenceTypes/);
|
|
280
|
+
assert.match(issueText, /unsafe_source\.forbiddenAuthority/);
|
|
281
|
+
assert.match(issueText, /Quarantined source is missing active quarantine status/);
|
|
252
282
|
assert.match(issueText, /Quarantined source cannot be reused directly/);
|
|
253
283
|
assert.match(issueText, /Quarantined source requests prompt import, direct execution, or lifecycle authority/);
|
|
254
284
|
} finally {
|
|
@@ -256,6 +286,57 @@ test('Phase 6.3 invalid agent runtime declarations fail closed', async () => {
|
|
|
256
286
|
}
|
|
257
287
|
});
|
|
258
288
|
|
|
289
|
+
test('Phase 8.6 capability routing selects narrow domains, packs, and rejected external sources', async () => {
|
|
290
|
+
const root = await mkdtemp(path.join(tmpdir(), 'sdd-phase86-capability-routing-'));
|
|
291
|
+
try {
|
|
292
|
+
await initProject(root);
|
|
293
|
+
await writeBranchDocs(root, 'master', `# Tasks
|
|
294
|
+
|
|
295
|
+
${capabilityRouteTaskMarkdown('SIMPLE', 'Simple backend parser fix', ['packages/core/src/parser.ts'], [], ['npm test'])}
|
|
296
|
+
${capabilityRouteTaskMarkdown('UI', 'UI UX frontend interaction update', ['src/components/Button.tsx'], ['ui-ux', 'accessibility'], ['browser Playwright validation'])}
|
|
297
|
+
${capabilityRouteTaskMarkdown('SECURITY', 'Security permission boundary update', ['packages/core/src/auth.ts'], ['security'], ['npm test'])}
|
|
298
|
+
${capabilityRouteTaskMarkdown('DB', 'Database migration data safety update', ['db/migrations/001.sql'], ['database', 'data-loss'], ['npm test'])}
|
|
299
|
+
${capabilityRouteTaskMarkdown('RELEASE', 'Release deploy rollback readiness', ['.github/workflows/release.yml'], ['release', 'ci-build'], ['npm test'])}
|
|
300
|
+
${capabilityRouteTaskMarkdown('TESTING', 'Testing quality coverage update', ['packages/core/src/parser.test.ts'], ['validation'], ['coverage acceptance test'])}`);
|
|
301
|
+
|
|
302
|
+
const simple = await routeSddTask(root, { taskId: 'SIMPLE', branch: 'master' });
|
|
303
|
+
const ui = await routeSddTask(root, { taskId: 'UI', branch: 'master' });
|
|
304
|
+
const security = await routeSddTask(root, { taskId: 'SECURITY', branch: 'master', approved: true });
|
|
305
|
+
const db = await routeSddTask(root, { taskId: 'DB', branch: 'master', approved: true });
|
|
306
|
+
const release = await routeSddTask(root, { taskId: 'RELEASE', branch: 'master', approved: true });
|
|
307
|
+
const testing = await routeSddTask(root, { taskId: 'TESTING', branch: 'master' });
|
|
308
|
+
const figmaConsidered = ui.capabilityDecision.consideredExternalSources.find((source) => source.sourceId === 'figma_design_future');
|
|
309
|
+
const uiUxProMaxConsidered = ui.capabilityDecision.consideredExternalSources.find((source) => source.sourceId === 'ui_ux_pro_max_external');
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
assert.deepEqual(simple.capabilityDecision.selectedDomains.map((item) => item.domain), ['backend-engineering']);
|
|
313
|
+
assert.equal(simple.capabilityDecision.selectedPacks.length <= 2, true);
|
|
314
|
+
assert.equal(simple.capabilityDecision.authority, 'advisory_only');
|
|
315
|
+
assert.equal(simple.capabilityDecision.permissionCeiling, simple.autonomyCeiling);
|
|
316
|
+
assert.equal(ui.capabilityDecision.selectedDomains.some((item) => item.domain === 'frontend-engineering'), true);
|
|
317
|
+
assert.equal(ui.capabilityDecision.selectedDomains.some((item) => item.domain === 'ui-ux-product-design'), true);
|
|
318
|
+
assert.equal(ui.capabilityDecision.selectedPacks.some((pack) => pack.id === 'baseline-ui-ux-product-design'), true);
|
|
319
|
+
assert.equal(ui.capabilityDecision.rejectedExternalSources.some((source) => source.sourceId === 'figma_design_future' && /Future adapter|quarantine/.test(source.reason)), true);
|
|
320
|
+
assert.equal(ui.capabilityDecision.rejectedExternalSources.some((source) => source.sourceId === 'ui_ux_pro_max_external' && /quarantine/i.test(source.reason)), true);
|
|
321
|
+
assert.ok(figmaConsidered);
|
|
322
|
+
assert.equal(figmaConsidered.kind, 'future_adapter');
|
|
323
|
+
assert.equal(figmaConsidered.consideredUse.length > 0, true);
|
|
324
|
+
assert.ok(uiUxProMaxConsidered);
|
|
325
|
+
assert.equal(uiUxProMaxConsidered.kind, 'open_source_material');
|
|
326
|
+
assert.equal(uiUxProMaxConsidered.quarantineStatus, 'quarantined');
|
|
327
|
+
assert.equal(security.capabilityDecision.selectedDomains.some((item) => item.domain === 'security-engineering'), true);
|
|
328
|
+
assert.equal(db.capabilityDecision.selectedDomains.some((item) => item.domain === 'db-data-engineering'), true);
|
|
329
|
+
assert.equal(release.capabilityDecision.selectedDomains.some((item) => item.domain === 'release-engineering'), true);
|
|
330
|
+
assert.equal(release.capabilityDecision.selectedPacks.some((pack) => pack.id === 'baseline-release-engineering'), true);
|
|
331
|
+
assert.equal(testing.capabilityDecision.selectedDomains.some((item) => item.domain === 'testing-quality-engineering'), true);
|
|
332
|
+
assert.equal(testing.capabilityDecision.evidenceRequirements.some((item) => item.includes('evidence requirement')), true);
|
|
333
|
+
assert.equal(ui.requiredCapabilities.includes('figma_design_future'), false);
|
|
334
|
+
} finally {
|
|
335
|
+
await rm(root, { recursive: true, force: true });
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
|
|
259
340
|
test('routeSddTask blocks downstream tasks until dependencies are completed', async () => {
|
|
260
341
|
const root = await mkdtemp(path.join(tmpdir(), 'sdd-route-dependencies-'));
|
|
261
342
|
try {
|
|
@@ -266,8 +347,8 @@ test('routeSddTask blocks downstream tasks until dependencies are completed', as
|
|
|
266
347
|
|
|
267
348
|
assert.equal(blocked.category, 'blocked');
|
|
268
349
|
assert.equal(blocked.recommendedProfile, null);
|
|
269
|
-
assert.match(blocked.blockedReason ?? '', /DEP2 depends on DEP1, but DEP1
|
|
270
|
-
assert.match(blocked.nextAction, /
|
|
350
|
+
assert.match(blocked.blockedReason ?? '', /DEP2 depends on DEP1, but DEP1 has not passed required verification/);
|
|
351
|
+
assert.match(blocked.nextAction, /sdd test task DEP1/);
|
|
271
352
|
|
|
272
353
|
await writeBranchDocs(root, 'feature', `# Tasks\n\n${validTaskMarkdown('DEP1', []).replace('status: pending', 'status: completed')}\n${validTaskMarkdown('DEP2', ['DEP1']).replace('packages/core/src/index.ts', 'docs/dep2.md')}`);
|
|
273
354
|
const ready = await routeSddTask(root, { taskId: 'DEP2', branch: 'feature' });
|
|
@@ -278,4 +359,71 @@ test('routeSddTask blocks downstream tasks until dependencies are completed', as
|
|
|
278
359
|
} finally {
|
|
279
360
|
await rm(root, { recursive: true, force: true });
|
|
280
361
|
}
|
|
281
|
-
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test('routeSddTask uses latest eligible runtime dependency readiness', async () => {
|
|
365
|
+
const root = await mkdtemp(path.join(tmpdir(), 'sdd-route-runtime-dependencies-'));
|
|
366
|
+
try {
|
|
367
|
+
await initProject(root);
|
|
368
|
+
await writeBranchDocs(root, 'feature', `# Tasks
|
|
369
|
+
|
|
370
|
+
${validTaskMarkdown('DEP1', [])
|
|
371
|
+
.replace('packages/core/src/index.ts', 'docs/dep1.md')
|
|
372
|
+
.replace('validation:\n - npm test', 'validation_batch: dep-batch\nvalidation_timing: batch_end\nrequires_verify_before_next: false\nvalidation:\n - npm test')}
|
|
373
|
+
${validTaskMarkdown('DEP2', ['DEP1']).replace('packages/core/src/index.ts', 'docs/dep2.md')}`);
|
|
374
|
+
const run = await createRun(root, { runId: 'run-dep1-implemented' });
|
|
375
|
+
await bindTestRunState(root, run.runId, 'feature', 'DEP1');
|
|
376
|
+
const bound = await readRunState(root, run.runId);
|
|
377
|
+
await writeRunState(root, {
|
|
378
|
+
...bound,
|
|
379
|
+
status: 'completed',
|
|
380
|
+
tasks: {
|
|
381
|
+
...bound.tasks,
|
|
382
|
+
DEP1: {
|
|
383
|
+
status: 'implemented_pending_validation',
|
|
384
|
+
implementationStatus: 'implemented',
|
|
385
|
+
verificationStatus: 'pending_batch',
|
|
386
|
+
validationBatch: 'dep-batch',
|
|
387
|
+
validationTiming: 'batch_end',
|
|
388
|
+
requiresVerifyBeforeNext: false,
|
|
389
|
+
gaps: [],
|
|
390
|
+
artifacts: []
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const decision = await routeSddTask(root, { taskId: 'DEP2', branch: 'feature' });
|
|
396
|
+
|
|
397
|
+
assert.notEqual(decision.category, 'blocked');
|
|
398
|
+
assert.equal(decision.blockedReason, null);
|
|
399
|
+
assert.ok(decision.recommendedProfile);
|
|
400
|
+
} finally {
|
|
401
|
+
await rm(root, { recursive: true, force: true });
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
function capabilityRouteTaskMarkdown(taskId: string, title: string, affectedFiles: string[], risk: string[], validation: string[]): string {
|
|
406
|
+
const affectedFilesBlock = affectedFiles.length === 0 ? 'affected_files: []' : `affected_files:\n${affectedFiles.map((file) => ` - ${file}`).join('\n')}`;
|
|
407
|
+
const riskBlock = risk.length === 0 ? 'risk: []' : `risk:\n${risk.map((item) => ` - ${item}`).join('\n')}`;
|
|
408
|
+
const validationBlock = validation.length === 0 ? 'validation: []' : `validation:\n${validation.map((item) => ` - ${item}`).join('\n')}`;
|
|
409
|
+
return `### ${taskId}: ${title}
|
|
410
|
+
|
|
411
|
+
\`\`\`sdd-task
|
|
412
|
+
id: ${taskId}
|
|
413
|
+
status: pending
|
|
414
|
+
wave: 1
|
|
415
|
+
depends_on: []
|
|
416
|
+
acceptance_refs:
|
|
417
|
+
- AC-1
|
|
418
|
+
${affectedFilesBlock}
|
|
419
|
+
${validationBlock}
|
|
420
|
+
${riskBlock}
|
|
421
|
+
allowed_agents:
|
|
422
|
+
- implementer
|
|
423
|
+
\`\`\`
|
|
424
|
+
|
|
425
|
+
#### Acceptance
|
|
426
|
+
|
|
427
|
+
- ${title}.
|
|
428
|
+
`;
|
|
429
|
+
}
|
|
@@ -11,11 +11,15 @@ import { buildAgentSkillRuntimeRegistry } from './runtime-registry.js';
|
|
|
11
11
|
import { buildTeamModePolicy, resolveTeamModeActivation } from './team-mode.js';
|
|
12
12
|
import { matchRoutingRules } from './routing-rules.js';
|
|
13
13
|
import { chooseRecommendedProfile, deriveAllowedProfiles, toAgentProfileId } from './profile-resolution.js';
|
|
14
|
-
import { adapterMappingForProfile, buildRejectedProfiles, buildToolPermissionSpec, modelPolicyForProfile, quarantineWarningsForSources, routeCategory, routeRegistrySources, selectRequiredSkillCapabilities } from './route-projection.js';
|
|
14
|
+
import { adapterMappingForProfile, buildAgentCapabilityRouteDecision, buildRejectedProfiles, buildToolPermissionSpec, modelPolicyForProfile, quarantineWarningsForSources, routeCategory, routeRegistrySources, selectRequiredSkillCapabilities } from './route-projection.js';
|
|
15
15
|
import { lifecycleAutonomyCeilingFromDecision, ensureLifecycleRiskDecision } from '../orchestration/runtime.js';
|
|
16
16
|
import { taskAutonomyCeiling } from './risk-policy.js';
|
|
17
17
|
import { evaluateTaskWorkflowGate } from '../risk.js';
|
|
18
18
|
import { nextDependencyTaskId, resolveTaskDependencyReadiness } from '../workflow-state/dependencies.js';
|
|
19
|
+
import { selectLatestEligibleRunsByTask, type LatestEligibleRunSelection } from '../workflow-state/latest-eligible-run.js';
|
|
20
|
+
import { readAllRunStates } from '../run-state/run-state.js';
|
|
21
|
+
import type { RunState, RunStateTaskRuntime } from '../run-state/model.js';
|
|
22
|
+
import { inspectAgentCapabilityCatalog } from '../registries/agent-capability-catalog.js';
|
|
19
23
|
import type {
|
|
20
24
|
AgentRouterDecision,
|
|
21
25
|
TeamModePolicy
|
|
@@ -46,10 +50,14 @@ export async function routeSddTask(projectRoot: string, options: { taskId: strin
|
|
|
46
50
|
const routeStart = Date.now();
|
|
47
51
|
const routeStartedAt = new Date(routeStart).toISOString();
|
|
48
52
|
const registry = await buildAgentSkillRuntimeRegistry(projectRoot);
|
|
53
|
+
const capabilityCatalog = await inspectAgentCapabilityCatalog(projectRoot);
|
|
49
54
|
profileSpans.push(runtimeProfileSpan('agent_runtime_registry', routeStart));
|
|
50
55
|
const branchStart = Date.now();
|
|
51
|
-
const
|
|
56
|
+
const context = await resolveSddContext(projectRoot, { branch: options.branch, branchSource: options.branch ? 'cli_option' : undefined });
|
|
57
|
+
const branch = context.partition;
|
|
52
58
|
const model = await parseSddBranch(projectRoot, branch);
|
|
59
|
+
const states = await readAllRunStates(projectRoot);
|
|
60
|
+
const runtimeByTask = latestRuntimeTaskStates(selectLatestEligibleRunsByTask({ states, model, partition: branch, currentGitBranch: context.currentGitBranch }), states);
|
|
53
61
|
profileSpans.push(runtimeProfileSpan('document_parse', branchStart));
|
|
54
62
|
const cacheKey = routeCacheKey({ taskId: options.taskId, branch, agent: options.agent ?? null, teamModeActivation: resolveTeamModeActivation(options, 'auto'), approved: options.approved, documents: model.documents });
|
|
55
63
|
const cachedDecision = options.cache ? await readRouteCache<AgentRouterDecision>(projectRoot, cacheKey) : null;
|
|
@@ -73,9 +81,9 @@ export async function routeSddTask(projectRoot: string, options: { taskId: strin
|
|
|
73
81
|
const lifecycleBlockedReason = workflowGate.blocksRoute
|
|
74
82
|
? workflowGate.primaryReason
|
|
75
83
|
: null;
|
|
76
|
-
const dependencyReadiness = task ? resolveTaskDependencyReadiness(model, options.taskId) : null;
|
|
84
|
+
const dependencyReadiness = task ? resolveTaskDependencyReadiness(model, options.taskId, { runtimeByTask }) : null;
|
|
77
85
|
const dependencyBlockedReason = dependencyReadiness?.blockingReasons[0] ?? null;
|
|
78
|
-
const dependencyTaskId = task ? nextDependencyTaskId(model, options.taskId) : null;
|
|
86
|
+
const dependencyTaskId = task ? nextDependencyTaskId(model, options.taskId, { runtimeByTask }) : null;
|
|
79
87
|
const taskRecommendedProfile = task && !blockingGap && !dependencyBlockedReason && !lifecycleBlockedReason ? chooseRecommendedProfile(task, allowedProfiles, registry, matchedRules) : null;
|
|
80
88
|
const recommendedProfile = dependencyBlockedReason || lifecycleBlockedReason ? null : delegatedProfile ?? taskRecommendedProfile;
|
|
81
89
|
const category = task ? routeCategory(task, blockingGap, allowedProfiles, matchedRules) : 'blocked';
|
|
@@ -87,6 +95,7 @@ export async function routeSddTask(projectRoot: string, options: { taskId: strin
|
|
|
87
95
|
const routedCategory = blockedReason ? 'blocked' : category;
|
|
88
96
|
const registrySources = routeRegistrySources(registry, recommendedProfile, requiredCapabilities);
|
|
89
97
|
const adapterMapping = recommendedProfile ? adapterMappingForProfile(registry, recommendedProfile) : null;
|
|
98
|
+
const capabilityDecision = buildAgentCapabilityRouteDecision(task ?? null, routedCategory, autonomyCeiling, registry, capabilityCatalog);
|
|
90
99
|
const decision: AgentRouterDecision = {
|
|
91
100
|
version: AGENT_ROUTER_CONTRACT_VERSION,
|
|
92
101
|
taskId: options.taskId,
|
|
@@ -116,7 +125,8 @@ export async function routeSddTask(projectRoot: string, options: { taskId: strin
|
|
|
116
125
|
primaryReason: workflowGate.primaryReason,
|
|
117
126
|
requiredArtifacts: task?.requiredArtifacts ?? [],
|
|
118
127
|
blockedReason,
|
|
119
|
-
nextAction: routeNextAction({ taskId: options.taskId, taskExists: Boolean(task), hasBlockingGap: Boolean(blockingGap), dependencyTaskId, workflowGateNextAction: workflowGate.nextAction, recommendedProfile, requiredCapabilities }),
|
|
128
|
+
nextAction: routeNextAction({ taskId: options.taskId, taskExists: Boolean(task), hasBlockingGap: Boolean(blockingGap), dependencyTaskId, blockedReason, workflowGateNextAction: workflowGate.nextAction, recommendedProfile, requiredCapabilities }),
|
|
129
|
+
capabilityDecision,
|
|
120
130
|
registrySources,
|
|
121
131
|
resolvedAliases: profileSelection.resolvedAliases,
|
|
122
132
|
routingRuleHits: matchedRules.map((rule) => rule.id),
|
|
@@ -135,11 +145,28 @@ export async function routeSddTask(projectRoot: string, options: { taskId: strin
|
|
|
135
145
|
return decision;
|
|
136
146
|
}
|
|
137
147
|
|
|
148
|
+
function latestRuntimeTaskStates(selections: LatestEligibleRunSelection[], states: RunState[]): Map<string, RunStateTaskRuntime> {
|
|
149
|
+
const stateByRunId = new Map(states.map((state) => [state.runId, state]));
|
|
150
|
+
const result = new Map<string, RunStateTaskRuntime>();
|
|
151
|
+
for (const selection of selections) {
|
|
152
|
+
const selected = selection.selected;
|
|
153
|
+
if (!selected) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const taskState = stateByRunId.get(selected.runId)?.tasks[selected.taskId];
|
|
157
|
+
if (taskState) {
|
|
158
|
+
result.set(selected.taskId, taskState);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
|
|
138
164
|
function routeNextAction(input: {
|
|
139
165
|
taskId: string;
|
|
140
166
|
taskExists: boolean;
|
|
141
167
|
hasBlockingGap: boolean;
|
|
142
168
|
dependencyTaskId: string | null;
|
|
169
|
+
blockedReason: string | null;
|
|
143
170
|
workflowGateNextAction: string;
|
|
144
171
|
recommendedProfile: string | null;
|
|
145
172
|
requiredCapabilities: string[];
|
|
@@ -151,7 +178,9 @@ function routeNextAction(input: {
|
|
|
151
178
|
return `Fix task gaps before routing ${input.taskId}.`;
|
|
152
179
|
}
|
|
153
180
|
if (input.dependencyTaskId) {
|
|
154
|
-
return
|
|
181
|
+
return input.blockedReason?.includes('has not passed required verification')
|
|
182
|
+
? `Run sdd test task ${input.dependencyTaskId} before routing ${input.taskId}.`
|
|
183
|
+
: `Run sdd do task ${input.dependencyTaskId} before routing ${input.taskId}.`;
|
|
155
184
|
}
|
|
156
185
|
if (input.workflowGateNextAction) {
|
|
157
186
|
return input.workflowGateNextAction;
|
|
@@ -80,13 +80,17 @@ export async function inspectExternalAgentPackImport(projectRoot: string, source
|
|
|
80
80
|
reason: 'Unknown external source cannot be routed.'
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
-
if (source.reuseDecision === 'avoid') {
|
|
83
|
+
if (source.reuseDecision === 'avoid' || source.quarantineStatus === 'denied') {
|
|
84
84
|
return {
|
|
85
85
|
version: EXTERNAL_AGENT_PACK_IMPORT_POLICY_VERSION,
|
|
86
86
|
sourceId,
|
|
87
87
|
status: 'denied',
|
|
88
|
-
checks: [
|
|
89
|
-
|
|
88
|
+
checks: [
|
|
89
|
+
{ check: 'reuse_decision', status: source.reuseDecision === 'avoid' ? 'fail' : 'warn', evidence: `${source.id} reuse=${source.reuseDecision}.` },
|
|
90
|
+
{ check: 'quarantine_status', status: source.quarantineStatus === 'denied' ? 'fail' : 'warn', evidence: `${source.id} quarantine_status=${source.quarantineStatus}.` },
|
|
91
|
+
{ check: 'host_compatibility', status: source.hostCompatibility.some((item) => item.includes('unsupported')) ? 'fail' : 'warn', evidence: source.hostCompatibility.join(',') || 'not declared' }
|
|
92
|
+
],
|
|
93
|
+
mappingResult: 'future adapter or unsupported source only',
|
|
90
94
|
allowedProfiles: [],
|
|
91
95
|
riskCeiling: 'research_before_implementation',
|
|
92
96
|
reason: source.rationale
|
|
@@ -98,11 +102,14 @@ export async function inspectExternalAgentPackImport(projectRoot: string, source
|
|
|
98
102
|
{ check: 'hidden_unicode_scan', status: 'not_run', evidence: 'External material has not been scanned for hidden Unicode.' },
|
|
99
103
|
{ check: 'secret_scan', status: 'not_run', evidence: 'External material has not been scanned for secrets.' },
|
|
100
104
|
{ check: 'dangerous_command_scan', status: 'not_run', evidence: 'External material has not been scanned for dangerous commands.' },
|
|
105
|
+
{ check: 'permission_model', status: source.permissionModel.length > 0 ? 'pass' : 'fail', evidence: source.permissionModel.join(',') || 'No permission model declared.' },
|
|
106
|
+
{ check: 'provenance_requirements', status: source.provenanceRequirements.length > 0 ? 'pass' : 'fail', evidence: source.provenanceRequirements.join(',') || 'No provenance requirements declared.' },
|
|
101
107
|
{ check: 'sdd_frontmatter_mapping', status: 'not_run', evidence: 'External material has not been mapped to SDD capability/profile fields.' }
|
|
102
108
|
]
|
|
103
109
|
: [
|
|
104
110
|
{ check: 'source_catalog', status: 'pass', evidence: `${source.id} is cataloged as ${source.reuseDecision}.` },
|
|
105
|
-
{ check: 'quarantine_required', status: 'pass', evidence: 'This source is a native capability or mechanism reference, not an imported prompt pack.' }
|
|
111
|
+
{ check: 'quarantine_required', status: 'pass', evidence: 'This source is a native capability or mechanism reference, not an imported prompt pack.' },
|
|
112
|
+
{ check: 'provenance_requirements', status: source.provenanceRequirements.length > 0 ? 'pass' : 'fail', evidence: source.provenanceRequirements.join(',') || 'No provenance requirements declared.' }
|
|
106
113
|
];
|
|
107
114
|
return {
|
|
108
115
|
version: EXTERNAL_AGENT_PACK_IMPORT_POLICY_VERSION,
|