@fitlab-ai/agent-infra 0.9.12 → 0.9.14
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 +11 -11
- package/README.zh-CN.md +11 -11
- package/bin/cli.ts +26 -9
- package/dist/bin/cli.js +173 -157
- package/dist/bin/internal-cli.js +66 -40
- package/dist/lib/agent-client.js +5 -0
- package/dist/lib/agent-clients/next-steps.js +6 -1
- package/dist/lib/decide.js +3 -3
- package/dist/lib/internal/agent-client.js +5 -2
- package/dist/lib/internal/cli-route-inventory.js +152 -0
- package/dist/lib/internal/codex-lifecycle.js +9 -6
- package/dist/lib/internal/codex-sandbox-controller.js +8 -2
- package/dist/lib/internal/git-workflow.js +10 -6
- package/dist/lib/internal/platform-checks.js +19 -7
- package/dist/lib/internal/platform-comment.js +25 -13
- package/dist/lib/internal/platform-context.js +6 -3
- package/dist/lib/internal/platform-issue.js +20 -13
- package/dist/lib/internal/platform-metadata.js +88 -0
- package/dist/lib/internal/platform-pr-review.js +26 -13
- package/dist/lib/internal/platform-pr.js +84 -31
- package/dist/lib/internal/platform-release-notes.js +9 -6
- package/dist/lib/internal/platform-security.js +93 -0
- package/dist/lib/internal/pr-review-grade.js +25 -12
- package/dist/lib/internal/release-workflow.js +23 -9
- package/dist/lib/internal/sandbox-control.js +50 -7
- package/dist/lib/internal/task-activity.js +16 -7
- package/dist/lib/internal/task-artifact.js +235 -24
- package/dist/lib/internal/task-context.js +4 -1
- package/dist/lib/internal/task-create.js +50 -17
- package/dist/lib/internal/task-delivery.js +4 -1
- package/dist/lib/internal/task-event.js +10 -4
- package/dist/lib/internal/task-finalization.js +6 -3
- package/dist/lib/internal/task-invalidation.js +63 -0
- package/dist/lib/internal/task-ledger.js +20 -6
- package/dist/lib/internal/task-lifecycle.js +6 -3
- package/dist/lib/internal/task-operation-registry.js +421 -0
- package/dist/lib/internal/task-orchestration.js +12 -0
- package/dist/lib/internal/task-override.js +14 -7
- package/dist/lib/internal/task-qualification.js +90 -0
- package/dist/lib/internal/task-review.js +7 -4
- package/dist/lib/internal/task-short-id.js +11 -1
- package/dist/lib/internal/task-snapshot.js +4 -1
- package/dist/lib/internal/task-validate.js +7 -2
- package/dist/lib/internal/task-verify.js +11 -7
- package/dist/lib/internal/task-warning.js +11 -4
- package/dist/lib/platform/adapters.js +1 -3
- package/dist/lib/platform/change-request-git-evidence.js +27 -7
- package/dist/lib/platform/comment-safety.js +226 -0
- package/dist/lib/platform/completion-backfill.js +6 -5
- package/dist/lib/platform/context.js +70 -130
- package/dist/lib/platform/github-client.js +1 -1
- package/dist/lib/platform/github-provider.js +1130 -0
- package/dist/lib/platform/in-label-sync.js +143 -0
- package/dist/lib/platform/issue-comments.js +237 -72
- package/dist/lib/platform/issues.js +335 -189
- package/dist/lib/platform/metadata-labels.js +6 -2
- package/dist/lib/platform/none-provider.js +28 -0
- package/dist/lib/platform/pr-change-report.js +545 -0
- package/dist/lib/platform/pr-checks.js +119 -104
- package/dist/lib/platform/pr-review.js +88 -72
- package/dist/lib/platform/pr-summary.js +541 -50
- package/dist/lib/platform/provider-bridge.js +45 -0
- package/dist/lib/platform/provider-contract.d.ts +553 -0
- package/dist/lib/platform/provider-contract.js +99 -0
- package/dist/lib/platform/provider-loader.js +251 -0
- package/dist/lib/platform/provider-validation.js +577 -0
- package/dist/lib/platform/pull-request-metadata.js +8 -6
- package/dist/lib/platform/pull-requests.js +734 -543
- package/dist/lib/platform/release-notes.js +78 -55
- package/dist/lib/platform/releases.js +79 -50
- package/dist/lib/platform/repository-metadata.js +377 -0
- package/dist/lib/platform/resource-identity.d.ts +26 -0
- package/dist/lib/platform/resource-identity.js +92 -0
- package/dist/lib/platform/security-alerts.js +155 -0
- package/dist/lib/platform/task-identities.js +31 -0
- package/dist/lib/platform/verification-required.js +11 -12
- package/dist/lib/platform/verification-sync.js +129 -248
- package/dist/lib/pr-review/evidence-grading.js +19 -6
- package/dist/lib/process-data/index.js +7 -0
- package/dist/lib/run/index.js +68 -23
- package/dist/lib/sandbox/commands/control-status.js +22 -0
- package/dist/lib/sandbox/commands/create.js +32 -6
- package/dist/lib/sandbox/commands/ls.js +5 -0
- package/dist/lib/sandbox/commands/rm.js +827 -120
- package/dist/lib/sandbox/commands/show.js +16 -0
- package/dist/lib/sandbox/control/client.js +174 -19
- package/dist/lib/sandbox/control/completed-reentry.js +85 -0
- package/dist/lib/sandbox/control/container-identity.js +28 -31
- package/dist/lib/sandbox/control/executor.js +151 -16
- package/dist/lib/sandbox/control/lifecycle.js +621 -127
- package/dist/lib/sandbox/control/native-file-lock.js +177 -0
- package/dist/lib/sandbox/control/protocol.js +77 -0
- package/dist/lib/sandbox/control/server.js +677 -34
- package/dist/lib/sandbox/control/state.js +209 -4
- package/dist/lib/sandbox/control/task-view.js +183 -0
- package/dist/lib/sandbox/engines/authority.js +289 -0
- package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
- package/dist/lib/sandbox/index.js +5 -0
- package/dist/lib/sandbox/recovery.js +21 -1
- package/dist/lib/sandbox/workspace-view.js +2 -1
- package/dist/lib/sandbox/worktree-safety.js +4 -1
- package/dist/lib/server/index.js +8 -0
- package/dist/lib/server/protocol.js +38 -1
- package/dist/lib/task/activity-log.js +8 -1
- package/dist/lib/task/artifact-lifecycle.js +75 -18
- package/dist/lib/task/artifact-operations.js +520 -0
- package/dist/lib/task/artifact-repair-intent.js +59 -0
- package/dist/lib/task/artifact-schema.js +135 -0
- package/dist/lib/task/capabilities.js +310 -0
- package/dist/lib/task/commands/status.js +32 -0
- package/dist/lib/task/commit-operation.js +12 -1
- package/dist/lib/task/control-authority.js +12 -5
- package/dist/lib/task/create-service.js +111 -12
- package/dist/lib/task/create.js +25 -0
- package/dist/lib/task/current-contract.js +5 -1
- package/dist/lib/task/decision-details.js +1 -1
- package/dist/lib/task/events.js +416 -17
- package/dist/lib/task/finalization.js +37 -13
- package/dist/lib/task/human-override.js +58 -36
- package/dist/lib/task/index.js +11 -3
- package/dist/lib/task/invalidation-command.js +86 -0
- package/dist/lib/task/invalidation.js +260 -0
- package/dist/lib/task/ledger-intents.js +37 -0
- package/dist/lib/task/local-artifact-finalization.js +299 -0
- package/dist/lib/task/orchestration.js +240 -144
- package/dist/lib/task/pr-delivery-fact.js +102 -101
- package/dist/lib/task/qualification-audit.js +490 -0
- package/dist/lib/task/qualification-confirmation.js +109 -0
- package/dist/lib/task/qualification-intents.js +148 -0
- package/dist/lib/task/review-artifacts.js +22 -23
- package/dist/lib/task/review-finalization.js +121 -4
- package/dist/lib/task/review-fingerprint.js +24 -2
- package/dist/lib/task/rework-intent.js +138 -0
- package/dist/lib/task/sections.js +6 -4
- package/dist/lib/task/skill-scope.js +23 -0
- package/dist/lib/task/task-execution-lock.js +27 -17
- package/dist/lib/task/verification-config.js +11 -0
- package/dist/lib/task/verification-engine.js +93 -16
- package/dist/lib/task/verification.js +3 -3
- package/dist/lib/task/workflow-warning-intents.js +1 -1
- package/dist/lib/task/write.js +11 -0
- package/dist/lib/version.js +11 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-client.ts +9 -0
- package/lib/agent-clients/next-steps.ts +6 -1
- package/lib/decide.ts +3 -3
- package/lib/init.ts +1 -1
- package/lib/internal/agent-client.ts +4 -2
- package/lib/internal/cli-route-inventory.ts +140 -0
- package/lib/internal/codex-lifecycle.ts +8 -6
- package/lib/internal/codex-sandbox-controller.ts +7 -2
- package/lib/internal/git-workflow.ts +9 -6
- package/lib/internal/platform-checks.ts +14 -6
- package/lib/internal/platform-comment.ts +20 -12
- package/lib/internal/platform-context.ts +5 -3
- package/lib/internal/platform-issue.ts +17 -11
- package/lib/internal/platform-metadata.ts +70 -0
- package/lib/internal/platform-pr-review.ts +23 -12
- package/lib/internal/platform-pr.ts +65 -27
- package/lib/internal/platform-release-notes.ts +8 -6
- package/lib/internal/platform-security.ts +83 -0
- package/lib/internal/pr-review-grade.ts +20 -11
- package/lib/internal/release-workflow.ts +21 -9
- package/lib/internal/sandbox-control.ts +44 -6
- package/lib/internal/task-activity.ts +15 -7
- package/lib/internal/task-artifact.ts +204 -22
- package/lib/internal/task-context.ts +3 -1
- package/lib/internal/task-create.ts +78 -17
- package/lib/internal/task-delivery.ts +3 -1
- package/lib/internal/task-event.ts +9 -4
- package/lib/internal/task-finalization.ts +6 -4
- package/lib/internal/task-invalidation.ts +41 -0
- package/lib/internal/task-ledger.ts +21 -8
- package/lib/internal/task-lifecycle.ts +5 -3
- package/lib/internal/task-operation-registry.ts +482 -0
- package/lib/internal/task-orchestration.ts +12 -0
- package/lib/internal/task-override.ts +15 -9
- package/lib/internal/task-qualification.ts +61 -0
- package/lib/internal/task-review.ts +6 -4
- package/lib/internal/task-short-id.ts +10 -1
- package/lib/internal/task-snapshot.ts +3 -1
- package/lib/internal/task-validate.ts +6 -2
- package/lib/internal/task-verify.ts +10 -7
- package/lib/internal/task-warning.ts +10 -4
- package/lib/platform/adapters.ts +3 -2
- package/lib/platform/change-request-git-evidence.ts +36 -9
- package/lib/platform/comment-safety.ts +250 -0
- package/lib/platform/completion-backfill.ts +9 -8
- package/lib/platform/context.ts +97 -134
- package/lib/platform/github-client.ts +2 -2
- package/lib/platform/github-provider.ts +1132 -0
- package/lib/platform/in-label-sync.ts +208 -0
- package/lib/platform/issue-comments.ts +255 -80
- package/lib/platform/issues.ts +344 -174
- package/lib/platform/metadata-labels.ts +5 -2
- package/lib/platform/none-provider.ts +35 -0
- package/lib/platform/pr-change-report.ts +639 -0
- package/lib/platform/pr-checks.ts +126 -106
- package/lib/platform/pr-review.ts +88 -85
- package/lib/platform/pr-summary.ts +581 -53
- package/lib/platform/provider-bridge.ts +82 -0
- package/lib/platform/provider-contract.ts +611 -0
- package/lib/platform/provider-loader.ts +307 -0
- package/lib/platform/provider-validation.ts +611 -0
- package/lib/platform/pull-request-metadata.ts +10 -7
- package/lib/platform/pull-requests.ts +781 -550
- package/lib/platform/release-notes.ts +76 -59
- package/lib/platform/releases.ts +77 -43
- package/lib/platform/repository-metadata.ts +453 -0
- package/lib/platform/resource-identity.ts +121 -0
- package/lib/platform/security-alerts.ts +191 -0
- package/lib/platform/task-identities.ts +40 -0
- package/lib/platform/types.ts +4 -2
- package/lib/platform/verification-required.ts +11 -13
- package/lib/platform/verification-sync.ts +128 -304
- package/lib/pr-review/evidence-grading.ts +25 -8
- package/lib/process-data/index.ts +7 -0
- package/lib/run/index.ts +62 -22
- package/lib/sandbox/commands/control-status.ts +26 -0
- package/lib/sandbox/commands/create.ts +46 -6
- package/lib/sandbox/commands/ls.ts +7 -0
- package/lib/sandbox/commands/rm.ts +1000 -87
- package/lib/sandbox/commands/show.ts +16 -0
- package/lib/sandbox/control/client.ts +203 -19
- package/lib/sandbox/control/completed-reentry.ts +98 -0
- package/lib/sandbox/control/container-identity.ts +27 -43
- package/lib/sandbox/control/executor.ts +180 -15
- package/lib/sandbox/control/lifecycle.ts +629 -17
- package/lib/sandbox/control/native-file-lock.ts +209 -0
- package/lib/sandbox/control/protocol.ts +118 -2
- package/lib/sandbox/control/server.ts +724 -34
- package/lib/sandbox/control/state.ts +257 -4
- package/lib/sandbox/control/task-view.ts +240 -0
- package/lib/sandbox/engines/authority.ts +365 -0
- package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
- package/lib/sandbox/index.ts +7 -0
- package/lib/sandbox/recovery.ts +21 -1
- package/lib/sandbox/workspace-view.ts +9 -3
- package/lib/sandbox/worktree-safety.ts +4 -1
- package/lib/server/index.ts +10 -0
- package/lib/server/protocol.ts +36 -1
- package/lib/task/activity-log.ts +8 -0
- package/lib/task/artifact-lifecycle.ts +70 -22
- package/lib/task/artifact-operations.ts +626 -0
- package/lib/task/artifact-repair-intent.ts +71 -0
- package/lib/task/artifact-schema.ts +192 -0
- package/lib/task/capabilities.ts +331 -0
- package/lib/task/commands/status.ts +38 -0
- package/lib/task/commit-operation.ts +12 -1
- package/lib/task/control-authority.ts +22 -9
- package/lib/task/create-service.ts +139 -14
- package/lib/task/create.ts +27 -0
- package/lib/task/current-contract.ts +6 -1
- package/lib/task/decision-details.ts +6 -2
- package/lib/task/events.ts +392 -16
- package/lib/task/finalization.ts +50 -14
- package/lib/task/human-override.ts +70 -46
- package/lib/task/index.ts +16 -3
- package/lib/task/invalidation-command.ts +86 -0
- package/lib/task/invalidation.ts +332 -0
- package/lib/task/ledger-intents.ts +35 -1
- package/lib/task/local-artifact-finalization.ts +432 -0
- package/lib/task/orchestration.ts +223 -133
- package/lib/task/pr-delivery-fact.ts +131 -148
- package/lib/task/qualification-audit.ts +599 -0
- package/lib/task/qualification-confirmation.ts +117 -0
- package/lib/task/qualification-intents.ts +150 -0
- package/lib/task/review-artifacts.ts +21 -22
- package/lib/task/review-finalization.ts +133 -4
- package/lib/task/review-fingerprint.ts +23 -2
- package/lib/task/rework-intent.ts +165 -0
- package/lib/task/sections.ts +6 -4
- package/lib/task/skill-scope.ts +24 -0
- package/lib/task/task-execution-lock.ts +23 -14
- package/lib/task/verification-config.ts +12 -0
- package/lib/task/verification-engine.ts +103 -17
- package/lib/task/verification.ts +4 -4
- package/lib/task/workflow-warning-intents.ts +1 -1
- package/lib/task/write.ts +19 -0
- package/lib/update.ts +1 -1
- package/lib/version.ts +15 -1
- package/package.json +12 -1
- package/templates/.agents/rules/README.en.md +3 -1
- package/templates/.agents/rules/README.zh-CN.md +3 -1
- package/templates/.agents/rules/decision-qualification.en.md +22 -0
- package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
- package/templates/.agents/rules/evidence-reporting.en.md +28 -0
- package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
- package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +2 -0
- package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
- package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
- package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
- package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
- package/templates/.agents/rules/pr-sync.en.md +10 -4
- package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
- package/templates/.agents/rules/security-alerts.en.md +8 -8
- package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
- package/templates/.agents/rules/task-short-id.en.md +1 -4
- package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
- package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
- package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
- package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
- package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
- package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
- package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
- package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
- package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
- package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
- package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
- package/templates/.agents/skills/create-pr/config/verify.json +1 -0
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
- package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
- package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
- package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
- package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
- package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
- package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
- package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
- package/templates/.agents/skills/test/SKILL.en.md +13 -2
- package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
- package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
- package/templates/.agents/templates/task.en.md +24 -1
- package/templates/.agents/templates/task.zh-CN.md +24 -1
- package/templates/.github/workflows/pr-label.yml +7 -26
- package/templates/.agents/scripts/security-alerts.github.sh +0 -151
- package/templates/.agents/scripts/security-alerts.sh +0 -31
- package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
- package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
- package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const ARTIFACT_FAMILY_CATALOG = [
|
|
2
|
+
{ family: 'analysis', sectionAliases: ['分析', 'Analysis'], heading: '分析', labels: ['需求分析报告', 'Requirements Analysis'] },
|
|
3
|
+
{ family: 'review-analysis', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['需求分析审查', 'Analysis Review'] },
|
|
4
|
+
{ family: 'plan', sectionAliases: ['设计', 'Design'], heading: '设计', labels: ['技术方案', 'Technical Plan'] },
|
|
5
|
+
{ family: 'review-plan', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['技术方案审查', 'Plan Review'] },
|
|
6
|
+
{ family: 'code', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['实现报告', 'Implementation Report'] },
|
|
7
|
+
{ family: 'review-code', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['代码审查', 'Code Review'] },
|
|
8
|
+
{ family: 'manual-validation', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['人工验证', 'Manual Validation'] },
|
|
9
|
+
{ family: 'validation-run', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['验证运行证据', 'Validation Run Evidence'] },
|
|
10
|
+
{ family: 'pr-review', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['PR 审查报告', 'PR Review Report'] }
|
|
11
|
+
];
|
|
12
|
+
const LOCAL_SECTIONS = {
|
|
13
|
+
analysis: [
|
|
14
|
+
['source', '需求来源', 'Requirements Source'],
|
|
15
|
+
['understanding', '需求理解', 'Requirements Understanding'],
|
|
16
|
+
['files', '相关文件', 'Related Files'],
|
|
17
|
+
['impact', '影响评估', 'Impact Assessment'],
|
|
18
|
+
['risks', '技术风险', 'Technical Risks'],
|
|
19
|
+
['effort', '工作量和复杂度评估', 'Effort and Complexity Assessment'],
|
|
20
|
+
['state-check', '状态核对', 'State Check']
|
|
21
|
+
],
|
|
22
|
+
plan: [
|
|
23
|
+
['understanding', '问题理解', 'Problem Understanding'],
|
|
24
|
+
['constraints', '约束条件', 'Constraints'],
|
|
25
|
+
['options', '方案对比', 'Options Comparison'],
|
|
26
|
+
['approach', '技术方法', 'Technical Approach'],
|
|
27
|
+
['steps', '实施步骤', 'Implementation Steps'],
|
|
28
|
+
['files', '文件清单', 'File List'],
|
|
29
|
+
['verification', '验证策略', 'Verification Strategy'],
|
|
30
|
+
['state-check', '状态核对', 'State Check']
|
|
31
|
+
],
|
|
32
|
+
code: [
|
|
33
|
+
['input', '实现输入', 'Implementation Input'],
|
|
34
|
+
['files', '变更文件', 'Changed Files'],
|
|
35
|
+
['key-code', '关键代码说明', 'Key Code Notes'],
|
|
36
|
+
['tests', '测试结果', 'Test Results'],
|
|
37
|
+
['deviations', '与方案的差异', 'Differences from Plan'],
|
|
38
|
+
['review-focus', '供审查关注的内容', 'Review Focus'],
|
|
39
|
+
['state-check', '状态核对', 'State Check'],
|
|
40
|
+
['evidence', '证据原文', 'Raw Evidence']
|
|
41
|
+
],
|
|
42
|
+
'review-analysis': [
|
|
43
|
+
['summary', '审查摘要', 'Review Summary'],
|
|
44
|
+
['coverage', '检视覆盖声明', 'Inspection Coverage'],
|
|
45
|
+
['specialized-coverage', '需求分析专项覆盖', 'Requirements Analysis Coverage'],
|
|
46
|
+
['traceability', '追踪矩阵', 'Traceability Matrix'],
|
|
47
|
+
['issues', '问题清单', 'Findings'],
|
|
48
|
+
['non-blocking', '非阻塞建议', 'Non-blocking Suggestions'],
|
|
49
|
+
['manual-validation', '人工校验项', 'Manual Validation Items'],
|
|
50
|
+
['conclusion', '结论与建议', 'Conclusion and Recommendation'],
|
|
51
|
+
['state-check', '状态核对', 'State Check'],
|
|
52
|
+
['evidence', '证据原文', 'Raw Evidence'],
|
|
53
|
+
['self-critique', '自我质疑', 'Self-critique'],
|
|
54
|
+
['ledger-writeback', '审查分歧账本回写', 'Review Disagreement Ledger Write-back']
|
|
55
|
+
],
|
|
56
|
+
'review-plan': [
|
|
57
|
+
['summary', '审查摘要', 'Review Summary'],
|
|
58
|
+
['coverage', '检视覆盖声明', 'Inspection Coverage'],
|
|
59
|
+
['specialized-coverage', '技术方案架构覆盖', 'Technical Plan Architecture Coverage'],
|
|
60
|
+
['traceability', '追踪矩阵', 'Traceability Matrix'],
|
|
61
|
+
['issues', '问题清单', 'Findings'],
|
|
62
|
+
['non-blocking', '非阻塞建议', 'Non-blocking Suggestions'],
|
|
63
|
+
['manual-validation', '人工校验项', 'Manual Validation Items'],
|
|
64
|
+
['conclusion', '结论与建议', 'Conclusion and Recommendation'],
|
|
65
|
+
['state-check', '状态核对', 'State Check'],
|
|
66
|
+
['evidence', '证据原文', 'Raw Evidence'],
|
|
67
|
+
['self-critique', '自我质疑', 'Self-critique'],
|
|
68
|
+
['ledger-writeback', '审查分歧账本回写', 'Review Disagreement Ledger Write-back']
|
|
69
|
+
],
|
|
70
|
+
'review-code': [
|
|
71
|
+
['summary', '审查摘要', 'Review Summary'],
|
|
72
|
+
['coverage', '检视覆盖声明', 'Inspection Coverage'],
|
|
73
|
+
['specialized-coverage', '代码实现专项覆盖', 'Code Implementation Coverage'],
|
|
74
|
+
['traceability', '追踪矩阵', 'Traceability Matrix'],
|
|
75
|
+
['issues', '问题清单', 'Findings'],
|
|
76
|
+
['non-blocking', '非阻塞建议', 'Non-blocking Suggestions'],
|
|
77
|
+
['manual-validation', '人工校验项', 'Manual Validation Items'],
|
|
78
|
+
['conclusion', '结论与建议', 'Conclusion and Recommendation'],
|
|
79
|
+
['state-check', '状态核对', 'State Check'],
|
|
80
|
+
['evidence', '证据原文', 'Raw Evidence'],
|
|
81
|
+
['self-critique', '自我质疑', 'Self-critique'],
|
|
82
|
+
['ledger-writeback', '审查分歧账本回写', 'Review Disagreement Ledger Write-back']
|
|
83
|
+
]
|
|
84
|
+
};
|
|
85
|
+
function buildSections(family) {
|
|
86
|
+
return LOCAL_SECTIONS[family].map(([id, zh, en], index) => ({
|
|
87
|
+
id,
|
|
88
|
+
order: index + 1,
|
|
89
|
+
headings: { zh, en },
|
|
90
|
+
marker: `artifact-section:${family}:${id}`
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
const ARTIFACT_SCHEMAS = [
|
|
94
|
+
{ family: 'analysis', title: { zh: '需求分析报告', en: 'Requirements Analysis' }, sections: buildSections('analysis'), requiredPatterns: ['^\\$ '] },
|
|
95
|
+
{ family: 'review-analysis', title: { zh: '需求分析审查报告', en: 'Analysis Review Report' }, sections: buildSections('review-analysis'), requiredPatterns: ['^### (?:审查决定|Approval Decision)$', '^\\$ '] },
|
|
96
|
+
{ family: 'plan', title: { zh: '技术方案', en: 'Technical Plan' }, sections: buildSections('plan'), requiredPatterns: ['^\\$ '] },
|
|
97
|
+
{ family: 'review-plan', title: { zh: '技术方案审查报告', en: 'Plan Review Report' }, sections: buildSections('review-plan'), requiredPatterns: ['^### (?:审查决定|Approval Decision)$', '^\\$ '] },
|
|
98
|
+
{ family: 'code', title: { zh: '实现报告', en: 'Implementation Report' }, sections: buildSections('code'), requiredPatterns: ['^\\$ '] },
|
|
99
|
+
{ family: 'review-code', title: { zh: '代码审查报告', en: 'Code Review Report' }, sections: buildSections('review-code'), requiredPatterns: [
|
|
100
|
+
'^### (?:审查决定|Approval Decision)$',
|
|
101
|
+
'^\\$ ',
|
|
102
|
+
'^- \\*\\*(?:总体结论|Overall Verdict)\\*\\*[::]\\s*(?:通过|需要修改|拒绝|Approved|Changes Requested|Rejected)\\s*$',
|
|
103
|
+
'^- \\*\\*(?:审查基线提交|Review Baseline Commit)\\*\\*[::]\\s*\\S',
|
|
104
|
+
'^- \\*\\*(?:审查差异基线|Reviewed Diff Base)\\*\\*[::]\\s*[0-9a-f]{40,64}\\s*$',
|
|
105
|
+
'^- \\*\\*(?:审查差异指纹|Reviewed Diff Fingerprint)\\*\\*[::]\\s*sha256:[0-9a-f]{64}\\s*$',
|
|
106
|
+
'^- \\*\\*(?:审查快照树|Reviewed Snapshot Tree)\\*\\*[::]\\s*[0-9a-f]{40,64}\\s*$'
|
|
107
|
+
] }
|
|
108
|
+
];
|
|
109
|
+
function getArtifactSchema(family) {
|
|
110
|
+
return ARTIFACT_SCHEMAS.find((schema) => schema.family === family) ?? null;
|
|
111
|
+
}
|
|
112
|
+
function renderArtifactSkeleton(input) {
|
|
113
|
+
const schema = getArtifactSchema(input.family);
|
|
114
|
+
if (!schema)
|
|
115
|
+
throw new Error(`unknown artifact schema family '${input.family}'`);
|
|
116
|
+
const locale = input.locale ?? 'zh-CN';
|
|
117
|
+
const roundMatch = input.artifact.match(/-r(\d+)\.md$/);
|
|
118
|
+
const round = roundMatch ? Number(roundMatch[1]) : 1;
|
|
119
|
+
const title = schema.title[locale === 'en' ? 'en' : 'zh'];
|
|
120
|
+
const headings = locale === 'en' ? 'en' : 'zh';
|
|
121
|
+
const lines = [
|
|
122
|
+
`<!-- artifact-context:${input.taskId}:${input.family}:${round} -->`,
|
|
123
|
+
`# ${title}`,
|
|
124
|
+
''
|
|
125
|
+
];
|
|
126
|
+
for (const section of schema.sections) {
|
|
127
|
+
lines.push(`## ${section.headings[headings]}`);
|
|
128
|
+
lines.push(`<!-- ${section.marker} -->`);
|
|
129
|
+
lines.push('<!-- artifact-slot:empty -->');
|
|
130
|
+
lines.push('');
|
|
131
|
+
}
|
|
132
|
+
return `${lines.join('\n').trimEnd()}\n`;
|
|
133
|
+
}
|
|
134
|
+
export { ARTIFACT_FAMILY_CATALOG, ARTIFACT_SCHEMAS, getArtifactSchema, renderArtifactSkeleton };
|
|
135
|
+
//# sourceMappingURL=artifact-schema.js.map
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { invalidationBlocks, isArtifactInvalidated, parseInvalidationDocument } from './invalidation.js';
|
|
4
|
+
import { receiptForOutput } from './artifact-receipts.js';
|
|
5
|
+
import { parseTypedTaskFrontmatter } from './frontmatter.js';
|
|
6
|
+
import { parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from './ledger.js';
|
|
7
|
+
import { parseReviewSummary, resolveCanonicalVerdict } from './review-artifacts.js';
|
|
8
|
+
import { parseReworkIntentDocument } from './rework-intent.js';
|
|
9
|
+
import { sha256File } from './artifact-receipts.js';
|
|
10
|
+
import { hasOpenLifecycleExecution } from './activity-log.js';
|
|
11
|
+
import { parseQualificationAudit, parseTaskQualification } from './qualification-audit.js';
|
|
12
|
+
const ARTIFACT_AUDIT_FAMILIES = new Set(['analysis', 'review-analysis', 'plan', 'review-plan', 'code', 'review-code']);
|
|
13
|
+
const REASONS = new Set([
|
|
14
|
+
'user-request', 'new-requirement', 'upstream-fact-doubt', 'review-finding', 'retry', 'validation-rerun'
|
|
15
|
+
]);
|
|
16
|
+
function deny(reasonCode, ...evidence) {
|
|
17
|
+
return { allowed: false, reasonCode, evidence };
|
|
18
|
+
}
|
|
19
|
+
function allow(...evidence) {
|
|
20
|
+
return { allowed: true, reasonCode: 'CAPABILITY_ALLOWED', evidence };
|
|
21
|
+
}
|
|
22
|
+
function hasArtifact(facts, action) {
|
|
23
|
+
return (facts.artifacts[action]?.length ?? 0) > 0;
|
|
24
|
+
}
|
|
25
|
+
function canStart(action, facts, trigger) {
|
|
26
|
+
if (!trigger || trigger.requestedAction !== action)
|
|
27
|
+
return deny('TRIGGER_ACTION_MISMATCH', `requested=${trigger?.requestedAction ?? 'missing'}`);
|
|
28
|
+
if (!trigger.requestId || !trigger.requestId.trim())
|
|
29
|
+
return deny('TRIGGER_REQUEST_ID_REQUIRED');
|
|
30
|
+
if (!REASONS.has(trigger.reasonCode))
|
|
31
|
+
return deny('TRIGGER_REASON_INVALID');
|
|
32
|
+
if (trigger.sourceArtifact && !trigger.sourceSha256)
|
|
33
|
+
return deny('SOURCE_ARTIFACT_HASH_REQUIRED');
|
|
34
|
+
if (trigger.sourceSha256 && !trigger.sourceArtifact)
|
|
35
|
+
return deny('SOURCE_ARTIFACT_REQUIRED');
|
|
36
|
+
if (trigger.sourceArtifact && trigger.sourceSha256) {
|
|
37
|
+
const actual = facts.artifactHashes[trigger.sourceArtifact];
|
|
38
|
+
if (!actual)
|
|
39
|
+
return deny('SOURCE_ARTIFACT_MISSING', trigger.sourceArtifact);
|
|
40
|
+
if (actual !== trigger.sourceSha256)
|
|
41
|
+
return deny('SOURCE_ARTIFACT_HASH_MISMATCH', trigger.sourceArtifact);
|
|
42
|
+
}
|
|
43
|
+
if (facts.taskState !== 'active')
|
|
44
|
+
return deny('TASK_NOT_ACTIVE', `state=${facts.taskState}`);
|
|
45
|
+
if (invalidationBlocks(facts.invalidation))
|
|
46
|
+
return deny('INVALIDATION_INCOMPLETE');
|
|
47
|
+
if (facts.qualificationStale && facts.recommendedAction !== action) {
|
|
48
|
+
return deny('QUALIFICATION_STALE', ...(facts.qualificationStaleArtifacts ?? ['qualification audit is stale']));
|
|
49
|
+
}
|
|
50
|
+
if (facts.executionBusy)
|
|
51
|
+
return deny('EXECUTION_BUSY');
|
|
52
|
+
const implicit = trigger.explicitRequest === false;
|
|
53
|
+
if (action === 'analysis') {
|
|
54
|
+
if (!implicit || hasArtifact(facts, 'analysis') || facts.recommendedAction === 'analysis')
|
|
55
|
+
return allow('analysis-capability');
|
|
56
|
+
return deny('ANALYSIS_REQUEST_REQUIRES_EXPLICIT_TRIGGER');
|
|
57
|
+
}
|
|
58
|
+
if (action === 'review-analysis') {
|
|
59
|
+
return hasArtifact(facts, 'analysis') ? allow('analysis-artifact') : deny('ANALYSIS_ARTIFACT_REQUIRED');
|
|
60
|
+
}
|
|
61
|
+
if (action === 'plan') {
|
|
62
|
+
if (!hasArtifact(facts, 'review-analysis'))
|
|
63
|
+
return deny('ANALYSIS_REVIEW_REQUIRED');
|
|
64
|
+
if (!reviewMatchesLatest(facts, 'analysis', 'review-analysis'))
|
|
65
|
+
return deny('ANALYSIS_REVIEW_NOT_LATEST');
|
|
66
|
+
if (facts.reviews['review-analysis'] !== 'approved')
|
|
67
|
+
return deny('ANALYSIS_REVIEW_NOT_APPROVED');
|
|
68
|
+
if (facts.unresolvedLedger.analysis > 0)
|
|
69
|
+
return deny('ANALYSIS_LEDGER_BLOCKED', `unresolved=${facts.unresolvedLedger.analysis}`);
|
|
70
|
+
return allow('analysis-review-approved');
|
|
71
|
+
}
|
|
72
|
+
if (action === 'review-plan') {
|
|
73
|
+
return hasArtifact(facts, 'plan') ? allow('plan-artifact') : deny('PLAN_ARTIFACT_REQUIRED');
|
|
74
|
+
}
|
|
75
|
+
if (action === 'code') {
|
|
76
|
+
if (trigger.implementationInput) {
|
|
77
|
+
if (!hasArtifact(facts, 'review-code'))
|
|
78
|
+
return deny('CODE_REVIEW_REQUIRED');
|
|
79
|
+
if (!reviewMatchesLatest(facts, 'code', 'review-code'))
|
|
80
|
+
return deny('CODE_REVIEW_NOT_LATEST');
|
|
81
|
+
if (facts.reviews['review-code'] !== 'approved')
|
|
82
|
+
return deny('CODE_REVIEW_NOT_APPROVED');
|
|
83
|
+
return allow('implementation-input');
|
|
84
|
+
}
|
|
85
|
+
if (!hasArtifact(facts, 'review-plan'))
|
|
86
|
+
return deny('PLAN_REVIEW_REQUIRED');
|
|
87
|
+
if (!reviewMatchesLatest(facts, 'plan', 'review-plan'))
|
|
88
|
+
return deny('PLAN_REVIEW_NOT_LATEST');
|
|
89
|
+
if (facts.reviews['review-plan'] !== 'approved')
|
|
90
|
+
return deny('PLAN_REVIEW_NOT_APPROVED');
|
|
91
|
+
if (facts.unresolvedLedger.plan > 0)
|
|
92
|
+
return deny('PLAN_LEDGER_BLOCKED', `unresolved=${facts.unresolvedLedger.plan}`);
|
|
93
|
+
return allow('plan-review-approved');
|
|
94
|
+
}
|
|
95
|
+
if (action === 'review-code') {
|
|
96
|
+
return hasArtifact(facts, 'code') ? allow('code-artifact') : deny('CODE_ARTIFACT_REQUIRED');
|
|
97
|
+
}
|
|
98
|
+
if (action === 'manual-validation' || action === 'validation-run') {
|
|
99
|
+
if (!hasArtifact(facts, 'review-code'))
|
|
100
|
+
return deny('CODE_REVIEW_REQUIRED');
|
|
101
|
+
if (!reviewMatchesLatest(facts, 'code', 'review-code'))
|
|
102
|
+
return deny('CODE_REVIEW_NOT_LATEST');
|
|
103
|
+
if (facts.reviews['review-code'] !== 'approved')
|
|
104
|
+
return deny('CODE_REVIEW_NOT_APPROVED');
|
|
105
|
+
if (facts.unresolvedLedger.code > 0)
|
|
106
|
+
return deny('CODE_LEDGER_BLOCKED', `unresolved=${facts.unresolvedLedger.code}`);
|
|
107
|
+
return allow('code-review-approved');
|
|
108
|
+
}
|
|
109
|
+
return deny('CAPABILITY_ACTION_UNKNOWN');
|
|
110
|
+
}
|
|
111
|
+
function artifactRound(name) {
|
|
112
|
+
const match = /-r(\d+)\.md$/.exec(name);
|
|
113
|
+
return match ? Number(match[1]) : 1;
|
|
114
|
+
}
|
|
115
|
+
function latestArtifact(names) {
|
|
116
|
+
return [...names].sort((left, right) => artifactRound(right) - artifactRound(left) || left.localeCompare(right))[0] ?? null;
|
|
117
|
+
}
|
|
118
|
+
function reviewedInputName(content, expectedFamily) {
|
|
119
|
+
const header = content.split(/\r?\n/).findIndex((line) => /\*\*(?:审查输入|Review Input)\*\*[::]/.test(line));
|
|
120
|
+
if (header < 0)
|
|
121
|
+
return null;
|
|
122
|
+
const referenceBlock = content.split(/\r?\n/).slice(header, header + 12).join('\n');
|
|
123
|
+
const expected = new RegExp('`' + expectedFamily + '(?:-r[2-9]|-r[1-9]\\d+)?\\.md`');
|
|
124
|
+
return expected.exec(referenceBlock)?.[0].slice(1, -1) ?? null;
|
|
125
|
+
}
|
|
126
|
+
function reviewMatchesLatest(facts, source, review) {
|
|
127
|
+
const latestSource = latestArtifact(facts.artifacts[source] ?? []);
|
|
128
|
+
return Boolean(latestSource && facts.reviewedInputs?.[review] === latestSource);
|
|
129
|
+
}
|
|
130
|
+
function qualificationCandidateSnapshotMatches(audit, qualification) {
|
|
131
|
+
const current = new Map(qualification.candidates.map((candidate) => [candidate.candidateId, candidate]));
|
|
132
|
+
return audit.candidateQualifications.length === current.size && audit.candidateQualifications.every((row) => {
|
|
133
|
+
const candidate = current.get(row.candidateId);
|
|
134
|
+
return Boolean(candidate && candidate.status === row.status && candidate.impact === row.impact
|
|
135
|
+
&& candidate.evidence === row.evidence && candidate.constraintIds.join(',') === row.constraintIds.join(','));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const QUALIFICATION_RECOVERY_ORDER = [
|
|
139
|
+
{ action: 'analysis', pattern: /^analysis(?:-r\d+)?\.md$/ },
|
|
140
|
+
{ action: 'review-analysis', pattern: /^review-analysis(?:-r\d+)?\.md$/ },
|
|
141
|
+
{ action: 'plan', pattern: /^plan(?:-r\d+)?\.md$/ },
|
|
142
|
+
{ action: 'review-plan', pattern: /^review-plan(?:-r\d+)?\.md$/ },
|
|
143
|
+
{ action: 'code', pattern: /^code(?:-r\d+)?\.md$/ },
|
|
144
|
+
{ action: 'review-code', pattern: /^review-code(?:-r\d+)?\.md$/ }
|
|
145
|
+
];
|
|
146
|
+
function qualificationRecoveryAction(facts) {
|
|
147
|
+
const stale = facts.qualificationStaleArtifacts ?? [];
|
|
148
|
+
return QUALIFICATION_RECOVERY_ORDER.find(({ pattern }) => stale.some((name) => pattern.test(name)))?.action ?? null;
|
|
149
|
+
}
|
|
150
|
+
function recommendNext(facts) {
|
|
151
|
+
if (invalidationBlocks(facts.invalidation))
|
|
152
|
+
return { action: null, reasonCode: 'INVALIDATION_INCOMPLETE', evidence: ['reconcile task invalidation before routing'] };
|
|
153
|
+
if (facts.qualificationStale) {
|
|
154
|
+
const action = qualificationRecoveryAction(facts);
|
|
155
|
+
return {
|
|
156
|
+
action,
|
|
157
|
+
reasonCode: 'QUALIFICATION_RECOVERY_REQUIRED',
|
|
158
|
+
evidence: facts.qualificationStaleArtifacts ?? ['qualification audit is stale']
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const pendingIntent = (facts.reworkIntents ?? []).find((intent) => intent.status === 'pending');
|
|
162
|
+
if (pendingIntent)
|
|
163
|
+
return { action: pendingIntent.target, reasonCode: 'REWORK_INTENT_PENDING', evidence: [pendingIntent.intentId, pendingIntent.findingId] };
|
|
164
|
+
if (!hasArtifact(facts, 'analysis'))
|
|
165
|
+
return { action: 'analysis', reasonCode: 'ANALYSIS_ARTIFACT_MISSING', evidence: ['analysis artifact is absent'] };
|
|
166
|
+
if (!hasArtifact(facts, 'review-analysis') || !reviewMatchesLatest(facts, 'analysis', 'review-analysis')) {
|
|
167
|
+
return { action: 'review-analysis', reasonCode: 'ANALYSIS_REVIEW_MISSING', evidence: ['analysis review does not bind the latest analysis artifact'] };
|
|
168
|
+
}
|
|
169
|
+
if (facts.reviews['review-analysis'] !== 'approved' || facts.unresolvedLedger.analysis > 0) {
|
|
170
|
+
return { action: 'analysis', reasonCode: 'ANALYSIS_REWORK_REQUIRED', evidence: ['analysis review or ledger is not clear'] };
|
|
171
|
+
}
|
|
172
|
+
if (!hasArtifact(facts, 'plan'))
|
|
173
|
+
return { action: 'plan', reasonCode: 'PLAN_ARTIFACT_MISSING', evidence: ['plan artifact is absent'] };
|
|
174
|
+
if (!hasArtifact(facts, 'review-plan') || !reviewMatchesLatest(facts, 'plan', 'review-plan')) {
|
|
175
|
+
return { action: 'review-plan', reasonCode: 'PLAN_REVIEW_MISSING', evidence: ['plan review does not bind the latest plan artifact'] };
|
|
176
|
+
}
|
|
177
|
+
if (facts.reviews['review-plan'] !== 'approved' || facts.unresolvedLedger.plan > 0) {
|
|
178
|
+
return { action: 'plan', reasonCode: 'PLAN_REWORK_REQUIRED', evidence: ['plan review or ledger is not clear'] };
|
|
179
|
+
}
|
|
180
|
+
if (!hasArtifact(facts, 'code'))
|
|
181
|
+
return { action: 'code', reasonCode: 'CODE_ARTIFACT_MISSING', evidence: ['code artifact is absent'] };
|
|
182
|
+
if (!hasArtifact(facts, 'review-code') || !reviewMatchesLatest(facts, 'code', 'review-code')) {
|
|
183
|
+
return { action: 'review-code', reasonCode: 'CODE_REVIEW_MISSING', evidence: ['code review does not bind the latest code artifact'] };
|
|
184
|
+
}
|
|
185
|
+
if (facts.reviews['review-code'] !== 'approved') {
|
|
186
|
+
return { action: 'code', reasonCode: 'CODE_REWORK_REQUIRED', evidence: ['code review or ledger is not clear'] };
|
|
187
|
+
}
|
|
188
|
+
return { action: null, reasonCode: 'LIFECYCLE_REVIEWED', evidence: ['latest code review is approved'] };
|
|
189
|
+
}
|
|
190
|
+
function buildLifecycleFacts(taskDir, content, taskState = 'active', executionBusy = false) {
|
|
191
|
+
try {
|
|
192
|
+
const metadata = parseTypedTaskFrontmatter(content);
|
|
193
|
+
const invalidation = parseInvalidationDocument(content);
|
|
194
|
+
if (!invalidation.ok)
|
|
195
|
+
return { ok: false, code: 'TASK_CAPABILITY_FACTS_INVALID', message: invalidation.message };
|
|
196
|
+
const rework = parseReworkIntentDocument(content);
|
|
197
|
+
if (!rework.ok)
|
|
198
|
+
return { ok: false, code: 'TASK_CAPABILITY_FACTS_INVALID', message: rework.message };
|
|
199
|
+
const ledger = parseLedgerDocument(content);
|
|
200
|
+
if (ledger.present) {
|
|
201
|
+
const invalid = validateLedgerRows(ledger.rows);
|
|
202
|
+
if (invalid)
|
|
203
|
+
return { ok: false, code: 'TASK_CAPABILITY_FACTS_INVALID', message: invalid.message };
|
|
204
|
+
}
|
|
205
|
+
const files = fs.readdirSync(taskDir).filter((name) => {
|
|
206
|
+
if (!name.endsWith('.md'))
|
|
207
|
+
return false;
|
|
208
|
+
const stat = fs.lstatSync(path.join(taskDir, name));
|
|
209
|
+
return stat.isFile() && !stat.isSymbolicLink();
|
|
210
|
+
});
|
|
211
|
+
const artifactFamilies = {
|
|
212
|
+
analysis: /^analysis(?:-r\d+)?\.md$/,
|
|
213
|
+
'review-analysis': /^review-analysis(?:-r\d+)?\.md$/,
|
|
214
|
+
plan: /^plan(?:-r\d+)?\.md$/,
|
|
215
|
+
'review-plan': /^review-plan(?:-r\d+)?\.md$/,
|
|
216
|
+
code: /^code(?:-r\d+)?\.md$/,
|
|
217
|
+
'review-code': /^review-code(?:-r\d+)?\.md$/
|
|
218
|
+
};
|
|
219
|
+
const familyFor = (name) => Object.keys(artifactFamilies)
|
|
220
|
+
.find((family) => artifactFamilies[family].test(name)) ?? null;
|
|
221
|
+
const activeFiles = files.filter((name) => {
|
|
222
|
+
const family = familyFor(name);
|
|
223
|
+
return !family || !isArtifactInvalidated(invalidation.document, family, name);
|
|
224
|
+
});
|
|
225
|
+
const artifactHashes = {};
|
|
226
|
+
for (const name of activeFiles)
|
|
227
|
+
artifactHashes[name] = sha256File(path.join(taskDir, name));
|
|
228
|
+
const artifacts = Object.fromEntries(Object.keys(artifactFamilies).map((family) => [
|
|
229
|
+
family, activeFiles.filter((name) => artifactFamilies[family].test(name))
|
|
230
|
+
]));
|
|
231
|
+
const staleArtifacts = Object.fromEntries(Object.keys(artifactFamilies).map((family) => [
|
|
232
|
+
family, files.filter((name) => artifactFamilies[family].test(name) && isArtifactInvalidated(invalidation.document, family, name))
|
|
233
|
+
]));
|
|
234
|
+
const qualification = parseTaskQualification(content);
|
|
235
|
+
if (!qualification.ok)
|
|
236
|
+
return { ok: false, code: 'TASK_CAPABILITY_FACTS_INVALID', message: qualification.message };
|
|
237
|
+
const qualificationStaleArtifacts = [];
|
|
238
|
+
if (qualification.qualification.present) {
|
|
239
|
+
const constraints = new Map(qualification.qualification.constraints.map((row) => [row.constraintId, row.digest]));
|
|
240
|
+
for (const family of Object.keys(artifactFamilies)) {
|
|
241
|
+
if (!ARTIFACT_AUDIT_FAMILIES.has(family))
|
|
242
|
+
continue;
|
|
243
|
+
const name = latestArtifact(artifacts[family] ?? []);
|
|
244
|
+
if (!name)
|
|
245
|
+
continue;
|
|
246
|
+
let auditContent;
|
|
247
|
+
try {
|
|
248
|
+
auditContent = fs.readFileSync(path.join(taskDir, name), 'utf8');
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
qualificationStaleArtifacts.push(name);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const audit = parseQualificationAudit(auditContent);
|
|
255
|
+
if (!audit.ok || !audit.audit.present || !audit.audit.snapshot) {
|
|
256
|
+
qualificationStaleArtifacts.push(name);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const constraintsChanged = audit.audit.constraintDependencies.some((dependency) => constraints.get(dependency.constraintId) !== dependency.constraintDigest);
|
|
260
|
+
const taskInputChanged = audit.audit.snapshot.taskInputDigest !== qualification.qualification.taskInputDigest;
|
|
261
|
+
if (audit.audit.snapshot.nonConstraintInputDigest !== qualification.qualification.nonConstraintInputDigest
|
|
262
|
+
|| constraintsChanged
|
|
263
|
+
|| (taskInputChanged && !constraintsChanged)
|
|
264
|
+
|| (taskInputChanged && !qualificationCandidateSnapshotMatches(audit.audit, qualification.qualification)))
|
|
265
|
+
qualificationStaleArtifacts.push(name);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const reviews = {};
|
|
269
|
+
const reviewedInputs = {};
|
|
270
|
+
for (const family of ['review-analysis', 'review-plan', 'review-code']) {
|
|
271
|
+
const latest = latestArtifact(artifacts[family] ?? []);
|
|
272
|
+
if (!latest)
|
|
273
|
+
continue;
|
|
274
|
+
const reviewContent = fs.readFileSync(path.join(taskDir, latest), 'utf8');
|
|
275
|
+
const expectedFamily = family === 'review-analysis' ? 'analysis' : family === 'review-plan' ? 'plan' : 'code';
|
|
276
|
+
const input = reviewedInputName(reviewContent, expectedFamily);
|
|
277
|
+
const receipt = input ? receiptForOutput(content, latest) : null;
|
|
278
|
+
if (input && receipt?.input === input && artifactHashes[input] === receipt.inputSha256)
|
|
279
|
+
reviewedInputs[family] = input;
|
|
280
|
+
const parsed = parseReviewSummary(reviewContent);
|
|
281
|
+
if (!parsed.ok)
|
|
282
|
+
continue;
|
|
283
|
+
const verdict = resolveCanonicalVerdict(parsed.summary);
|
|
284
|
+
if (verdict.ok)
|
|
285
|
+
reviews[family] = verdict.verdict === 'Approved' ? 'approved' : verdict.verdict === 'Changes Requested' ? 'changes-requested' : 'rejected';
|
|
286
|
+
}
|
|
287
|
+
const unresolvedLedger = { analysis: 0, plan: 0, code: 0 };
|
|
288
|
+
if (ledger.present) {
|
|
289
|
+
for (const stage of ['analysis', 'plan', 'code'])
|
|
290
|
+
unresolvedLedger[stage] = summarizeLedgerStage(ledger.rows, stage).unresolved.length;
|
|
291
|
+
}
|
|
292
|
+
const facts = {
|
|
293
|
+
taskState, currentStep: String(metadata.current_step ?? ''), artifacts, reviews,
|
|
294
|
+
staleArtifacts, reviewedInputs, artifactHashes,
|
|
295
|
+
invalidation: invalidation.document, reworkIntents: rework.intents,
|
|
296
|
+
unresolvedLedger,
|
|
297
|
+
executionBusy: executionBusy || hasOpenLifecycleExecution(content),
|
|
298
|
+
recommendedAction: null,
|
|
299
|
+
qualificationStale: qualificationStaleArtifacts.length > 0,
|
|
300
|
+
qualificationStaleArtifacts
|
|
301
|
+
};
|
|
302
|
+
facts.recommendedAction = recommendNext(facts).action;
|
|
303
|
+
return { ok: true, facts };
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return { ok: false, code: 'TASK_CAPABILITY_FACTS_INVALID', message: error instanceof Error ? error.message : String(error) };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
export { buildLifecycleFacts, canStart, recommendNext };
|
|
310
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -11,6 +11,9 @@ import { getOpenWorkflowWarnings, formatWorkflowWarningSummary } from '../workfl
|
|
|
11
11
|
import { parseActivityLog, pairEntries, startedBackedRows } from '../activity-log.js';
|
|
12
12
|
import { readRun } from '../orchestration.js';
|
|
13
13
|
import { statusCard } from '../../server/display.js';
|
|
14
|
+
import { invalidationBlocks, parseInvalidationDocument } from '../invalidation.js';
|
|
15
|
+
import { parseReworkIntentDocument } from '../rework-intent.js';
|
|
16
|
+
import { buildLifecycleFacts, recommendNext } from '../capabilities.js';
|
|
14
17
|
const USAGE = `Usage: ai task status [--task <ref> | -t <ref>]
|
|
15
18
|
|
|
16
19
|
Prints an aggregated "health check" view for a task: header, metadata,
|
|
@@ -317,6 +320,12 @@ function renderStatus(model) {
|
|
|
317
320
|
else {
|
|
318
321
|
lines.push(...renderPairs(model.artifacts.groups.map((group) => [group.stage, group.files.join(', ')])));
|
|
319
322
|
}
|
|
323
|
+
lines.push('', 'Invalidation', ...renderPairs([
|
|
324
|
+
['status', model.invalidation?.status ?? 'unknown'],
|
|
325
|
+
['processed', `${model.invalidation?.processed ?? 0}/${model.invalidation?.total ?? 0}`],
|
|
326
|
+
['pending_intents', String(model.invalidation?.pendingIntents ?? 0)]
|
|
327
|
+
]));
|
|
328
|
+
lines.push('', 'Recommendation', ...renderPairs([['action', model.recommendation ?? DASH]]));
|
|
320
329
|
lines.push('', 'Orchestration', ...renderPairs([
|
|
321
330
|
['status', model.orchestration.status],
|
|
322
331
|
['run_id', model.orchestration.runId],
|
|
@@ -361,6 +370,10 @@ function renderStatus(model) {
|
|
|
361
370
|
return lines;
|
|
362
371
|
}
|
|
363
372
|
function modelTone(model) {
|
|
373
|
+
if (model.invalidation?.status === 'invalid')
|
|
374
|
+
return 'danger';
|
|
375
|
+
if (model.invalidation?.status === 'pending' || model.invalidation?.status === 'in-progress')
|
|
376
|
+
return 'warning';
|
|
364
377
|
if (model.orchestration.status === 'paused')
|
|
365
378
|
return 'warning';
|
|
366
379
|
if (model.orchestration.status === 'running')
|
|
@@ -382,6 +395,23 @@ function buildFromResolved(input) {
|
|
|
382
395
|
const run = input.run ?? makeRunner(input.repoRoot);
|
|
383
396
|
const artifacts = enumerateArtifacts(input.taskDir);
|
|
384
397
|
const workflow = collectWorkflow(content, input.now);
|
|
398
|
+
const invalidation = parseInvalidationDocument(content);
|
|
399
|
+
const rework = parseReworkIntentDocument(content);
|
|
400
|
+
const pendingIntents = rework.ok ? rework.intents.filter((intent) => intent.status === 'pending').length : 0;
|
|
401
|
+
const invalidationInfo = !invalidation.ok
|
|
402
|
+
? { status: 'invalid', processed: 0, total: 0, pendingIntents }
|
|
403
|
+
: {
|
|
404
|
+
status: invalidation.present
|
|
405
|
+
? invalidationBlocks(invalidation.document)
|
|
406
|
+
? invalidation.document.operations.some((operation) => operation.status === 'in-progress') ? 'in-progress' : 'pending'
|
|
407
|
+
: 'completed'
|
|
408
|
+
: 'none',
|
|
409
|
+
processed: invalidation.document.operations.reduce((sum, operation) => sum + operation.processed, 0),
|
|
410
|
+
total: invalidation.document.operations.reduce((sum, operation) => sum + operation.total, 0),
|
|
411
|
+
pendingIntents
|
|
412
|
+
};
|
|
413
|
+
const facts = buildLifecycleFacts(input.taskDir, content, fm.status ?? 'active');
|
|
414
|
+
const recommendation = facts.ok ? (recommendNext(facts.facts).action ?? DASH) : DASH;
|
|
385
415
|
return {
|
|
386
416
|
taskId: input.taskId,
|
|
387
417
|
shortId: input.shortId ?? loadShortIdByTaskId(input.repoRoot).get(input.taskId) ?? DASH,
|
|
@@ -392,6 +422,8 @@ function buildFromResolved(input) {
|
|
|
392
422
|
workflow,
|
|
393
423
|
runtime: collectRuntime(input.taskDir, workflow, run),
|
|
394
424
|
orchestration: collectOrchestration(input.taskDir),
|
|
425
|
+
invalidation: invalidationInfo,
|
|
426
|
+
recommendation,
|
|
395
427
|
git: collectGit(fm.branch ?? '', run)
|
|
396
428
|
};
|
|
397
429
|
}
|
|
@@ -123,7 +123,18 @@ function syncTaskCommit(input, task, committedHead) {
|
|
|
123
123
|
return warning('TASK_STATUS_SYNC_FAILED', 'task has no unique Activity Log section', true, 'task', task.taskId, 'ACTION_REQUIRED');
|
|
124
124
|
const metadata = captureTaskWriteMetadata();
|
|
125
125
|
const commitNote = gitText(task.repoRoot, ['show', '-s', '--format=%h %s', committedHead]);
|
|
126
|
-
|
|
126
|
+
let matchingCommitIndex = -1;
|
|
127
|
+
for (let index = activity.entries.length - 1; index >= 0; index -= 1) {
|
|
128
|
+
const entry = activity.entries[index];
|
|
129
|
+
if (entry.step === 'Commit' && entry.note === commitNote) {
|
|
130
|
+
matchingCommitIndex = index;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const reviewedAfterCommit = matchingCommitIndex >= 0 && activity.entries
|
|
135
|
+
.slice(matchingCommitIndex + 1)
|
|
136
|
+
.some((entry) => /^Review Code \(Round \d+\)$/.test(entry.step));
|
|
137
|
+
const alreadyLogged = matchingCommitIndex >= 0 && !reviewedAfterCommit;
|
|
127
138
|
const mutations = [];
|
|
128
139
|
if (!alreadyLogged)
|
|
129
140
|
mutations.push({
|
|
@@ -52,6 +52,7 @@ export function createSandboxExecutorExecutionContext(params) {
|
|
|
52
52
|
generation: params.generation,
|
|
53
53
|
manifestPath: absolute('manifestPath', params.manifestPath),
|
|
54
54
|
requestId: params.requestId,
|
|
55
|
+
...(params.diagnosticLog === undefined ? {} : { diagnosticLog: params.diagnosticLog }),
|
|
55
56
|
...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) })
|
|
56
57
|
};
|
|
57
58
|
}
|
|
@@ -87,6 +88,9 @@ function domainOptions(context, options) {
|
|
|
87
88
|
return {
|
|
88
89
|
...options,
|
|
89
90
|
repoRoot: context.repoRoot,
|
|
91
|
+
...(context.source === 'sandbox-executor' && context.diagnosticLog !== undefined
|
|
92
|
+
? { diagnosticLog: context.diagnosticLog }
|
|
93
|
+
: {}),
|
|
90
94
|
...(context.source === 'sandbox-executor' ? { gitWorktreeRoot: context.worktreeRoot } : {})
|
|
91
95
|
};
|
|
92
96
|
}
|
|
@@ -101,12 +105,12 @@ function lifecycleTaskId(request, repoRoot) {
|
|
|
101
105
|
return null;
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
function applyLifecycleWithAuthority(context, request) {
|
|
108
|
+
async function applyLifecycleWithAuthority(context, request) {
|
|
105
109
|
const conflict = overrideDryRunConflict(request);
|
|
106
110
|
if (conflict) {
|
|
107
111
|
return taskLifecycleFailure(request, { code: 'LIFECYCLE_PAYLOAD_INVALID', message: conflict.message });
|
|
108
112
|
}
|
|
109
|
-
const execute = () => {
|
|
113
|
+
const execute = async () => {
|
|
110
114
|
const lifecycleResult = applyTaskLifecycle(request, { repoRoot: context.repoRoot });
|
|
111
115
|
if (lifecycleResult.status !== 'failed' || !request.overrideTicket)
|
|
112
116
|
return lifecycleResult;
|
|
@@ -116,7 +120,7 @@ function applyLifecycleWithAuthority(context, request) {
|
|
|
116
120
|
error: { code: 'OVERRIDE_PAYLOAD_INVALID', message: 'override ticket requires --override-target and --override-scope' }
|
|
117
121
|
};
|
|
118
122
|
}
|
|
119
|
-
const override = consumeHumanOverride({
|
|
123
|
+
const override = await consumeHumanOverride({
|
|
120
124
|
taskRef: request.taskRef,
|
|
121
125
|
ticketId: request.overrideTicket,
|
|
122
126
|
failureId: failureId('lifecycle.apply', lifecycleResult.error?.code ?? 'LIFECYCLE_FAILED'),
|
|
@@ -133,9 +137,9 @@ function applyLifecycleWithAuthority(context, request) {
|
|
|
133
137
|
};
|
|
134
138
|
const taskId = lifecycleTaskId(request, context.repoRoot);
|
|
135
139
|
if (!taskId)
|
|
136
|
-
return execute();
|
|
140
|
+
return await execute();
|
|
137
141
|
try {
|
|
138
|
-
return withTaskExecutionLock(context.repoRoot, taskId, `task-lifecycle.${request.intent}`, execute);
|
|
142
|
+
return await withTaskExecutionLock(context.repoRoot, taskId, `task-lifecycle.${request.intent}`, execute);
|
|
139
143
|
}
|
|
140
144
|
catch (error) {
|
|
141
145
|
if (!(error instanceof TaskExecutionLockError))
|
|
@@ -210,6 +214,9 @@ export function dispatchTaskControlOperation(context, operation) {
|
|
|
210
214
|
operationTaskId(context, operation.request.taskRef);
|
|
211
215
|
return applyTaskFinalization(operation.request, {
|
|
212
216
|
repoRoot: context.repoRoot,
|
|
217
|
+
...(context.source === 'sandbox-executor' ? {
|
|
218
|
+
controlBinding: { generation: context.generation, requestId: context.requestId }
|
|
219
|
+
} : {}),
|
|
213
220
|
preflight: (request, options) => verifyTaskEvent({ ...request, event: 'complete-task.hard-preflight' }, options)
|
|
214
221
|
});
|
|
215
222
|
}
|