@fitlab-ai/agent-infra 0.9.11 → 0.9.13
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 +13 -13
- package/README.zh-CN.md +13 -13
- package/dist/bin/internal-cli.js +29 -19
- package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
- package/dist/lib/agent-clients/next-steps.js +6 -1
- package/dist/lib/decide.js +3 -3
- package/dist/lib/defaults.json +4 -0
- package/dist/lib/git/workflow.js +43 -1
- package/dist/lib/init.js +1 -0
- package/dist/lib/internal/git-workflow.js +8 -1
- package/dist/lib/internal/platform-checks.js +3 -3
- package/dist/lib/internal/platform-comment.js +9 -9
- package/dist/lib/internal/platform-context.js +2 -2
- package/dist/lib/internal/platform-issue.js +8 -9
- package/dist/lib/internal/platform-pr-review.js +10 -10
- package/dist/lib/internal/platform-pr.js +68 -23
- package/dist/lib/internal/platform-release-notes.js +3 -3
- package/dist/lib/internal/pr-review-grade.js +11 -9
- package/dist/lib/internal/release-workflow.js +4 -4
- package/dist/lib/internal/sandbox-control.js +30 -4
- package/dist/lib/internal/task-activity.js +3 -3
- package/dist/lib/internal/task-artifact.js +76 -24
- package/dist/lib/internal/task-create.js +2 -2
- package/dist/lib/internal/task-delivery.js +59 -0
- package/dist/lib/internal/task-event.js +6 -3
- package/dist/lib/internal/task-finalization.js +2 -2
- package/dist/lib/internal/task-invalidation.js +60 -0
- package/dist/lib/internal/task-ledger.js +9 -6
- package/dist/lib/internal/task-lifecycle.js +2 -2
- package/dist/lib/internal/task-override.js +4 -4
- package/dist/lib/internal/task-review.js +3 -3
- package/dist/lib/internal/task-verify.js +6 -6
- package/dist/lib/internal/task-warning.js +3 -3
- package/dist/lib/platform/adapters.js +1 -3
- package/dist/lib/platform/change-request-git-evidence.js +27 -7
- package/dist/lib/platform/completion-backfill.js +6 -5
- package/dist/lib/platform/context.js +70 -130
- package/dist/lib/platform/github-client.js +8 -2
- package/dist/lib/platform/github-provider.js +903 -0
- package/dist/lib/platform/in-label-sync.js +143 -0
- package/dist/lib/platform/issue-comments.js +94 -41
- 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 +551 -0
- package/dist/lib/platform/pr-checks.js +124 -106
- package/dist/lib/platform/pr-review.js +88 -72
- package/dist/lib/platform/pr-summary.js +523 -49
- package/dist/lib/platform/provider-bridge.js +45 -0
- package/dist/lib/platform/provider-contract.d.ts +487 -0
- package/dist/lib/platform/provider-contract.js +95 -0
- package/dist/lib/platform/provider-loader.js +251 -0
- package/dist/lib/platform/provider-validation.js +504 -0
- package/dist/lib/platform/pull-request-metadata.js +8 -6
- package/dist/lib/platform/pull-requests.js +1050 -502
- package/dist/lib/platform/release-notes.js +78 -55
- package/dist/lib/platform/releases.js +79 -50
- package/dist/lib/platform/resource-identity.d.ts +26 -0
- package/dist/lib/platform/resource-identity.js +92 -0
- package/dist/lib/platform/task-identities.js +31 -0
- package/dist/lib/platform/verification-required.js +22 -12
- package/dist/lib/platform/verification-sync.js +118 -239
- package/dist/lib/pr-review/evidence-grading.js +30 -9
- package/dist/lib/run/index.js +63 -23
- package/dist/lib/sandbox/config.js +5 -0
- package/dist/lib/sandbox/control/client.js +96 -15
- package/dist/lib/sandbox/control/executor.js +3 -3
- package/dist/lib/sandbox/control/lifecycle.js +29 -7
- package/dist/lib/sandbox/control/protocol.js +77 -0
- package/dist/lib/sandbox/control/server.js +398 -25
- package/dist/lib/sandbox/control/state.js +204 -1
- package/dist/lib/server/process-state.js +2 -2
- package/dist/lib/server/protocol.js +38 -1
- package/dist/lib/task/activity-log.js +8 -1
- package/dist/lib/task/artifact-lifecycle.js +35 -7
- package/dist/lib/task/capabilities.js +239 -0
- package/dist/lib/task/commands/status.js +32 -0
- package/dist/lib/task/commit-intent.js +100 -0
- package/dist/lib/task/commit-operation.js +207 -102
- package/dist/lib/task/control-authority.js +8 -5
- package/dist/lib/task/create-service.js +8 -8
- package/dist/lib/task/create.js +33 -7
- package/dist/lib/task/current-contract.js +5 -1
- package/dist/lib/task/decision-details.js +3 -48
- package/dist/lib/task/delivery-target.js +97 -0
- package/dist/lib/task/delivery.js +153 -0
- package/dist/lib/task/events.js +297 -17
- package/dist/lib/task/finalization.js +37 -13
- package/dist/lib/task/human-override.js +61 -36
- 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/lifecycle.js +106 -9
- package/dist/lib/task/local-artifact-finalization.js +374 -0
- package/dist/lib/task/orchestration.js +100 -151
- package/dist/lib/task/pr-delivery-fact.js +183 -0
- package/dist/lib/task/review-finalization.js +4 -8
- package/dist/lib/task/review-fingerprint.js +32 -2
- package/dist/lib/task/rework-intent.js +138 -0
- package/dist/lib/task/skill-scope.js +23 -0
- package/dist/lib/task/task-execution-lock.js +27 -17
- package/dist/lib/task/verification-engine.js +89 -38
- package/dist/lib/task/verification-review.js +1 -1
- 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/update.js +9 -0
- package/dist/lib/version.js +11 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
- package/lib/agent-clients/next-steps.ts +6 -1
- package/lib/decide.ts +3 -3
- package/lib/defaults.json +4 -0
- package/lib/git/workflow.ts +38 -1
- package/lib/init.ts +4 -1
- package/lib/internal/git-workflow.ts +7 -1
- package/lib/internal/platform-checks.ts +3 -3
- package/lib/internal/platform-comment.ts +8 -8
- package/lib/internal/platform-context.ts +2 -2
- package/lib/internal/platform-issue.ts +7 -8
- package/lib/internal/platform-pr-review.ts +9 -9
- package/lib/internal/platform-pr.ts +53 -21
- package/lib/internal/platform-release-notes.ts +3 -3
- package/lib/internal/pr-review-grade.ts +10 -8
- package/lib/internal/release-workflow.ts +4 -4
- package/lib/internal/sandbox-control.ts +27 -3
- package/lib/internal/task-activity.ts +3 -3
- package/lib/internal/task-artifact.ts +65 -22
- package/lib/internal/task-create.ts +2 -2
- package/lib/internal/task-delivery.ts +53 -0
- package/lib/internal/task-event.ts +6 -3
- package/lib/internal/task-finalization.ts +3 -3
- package/lib/internal/task-invalidation.ts +39 -0
- package/lib/internal/task-ledger.ts +11 -8
- package/lib/internal/task-lifecycle.ts +2 -2
- package/lib/internal/task-override.ts +6 -6
- package/lib/internal/task-review.ts +3 -3
- package/lib/internal/task-verify.ts +6 -6
- package/lib/internal/task-warning.ts +3 -3
- package/lib/platform/adapters.ts +3 -2
- package/lib/platform/change-request-git-evidence.ts +36 -9
- package/lib/platform/completion-backfill.ts +9 -8
- package/lib/platform/context.ts +97 -134
- package/lib/platform/github-client.ts +10 -3
- package/lib/platform/github-provider.ts +910 -0
- package/lib/platform/in-label-sync.ts +208 -0
- package/lib/platform/issue-comments.ts +97 -47
- 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 +645 -0
- package/lib/platform/pr-checks.ts +129 -107
- package/lib/platform/pr-review.ts +88 -85
- package/lib/platform/pr-summary.ts +562 -52
- package/lib/platform/provider-bridge.ts +82 -0
- package/lib/platform/provider-contract.ts +536 -0
- package/lib/platform/provider-loader.ts +307 -0
- package/lib/platform/provider-validation.ts +529 -0
- package/lib/platform/pull-request-metadata.ts +10 -7
- package/lib/platform/pull-requests.ts +1126 -505
- package/lib/platform/release-notes.ts +76 -59
- package/lib/platform/releases.ts +77 -43
- package/lib/platform/resource-identity.ts +121 -0
- package/lib/platform/task-identities.ts +40 -0
- package/lib/platform/types.ts +4 -2
- package/lib/platform/verification-required.ts +21 -13
- package/lib/platform/verification-sync.ts +118 -293
- package/lib/pr-review/evidence-grading.ts +31 -11
- package/lib/run/index.ts +57 -22
- package/lib/sandbox/config.ts +7 -0
- package/lib/sandbox/control/client.ts +105 -15
- package/lib/sandbox/control/executor.ts +4 -4
- package/lib/sandbox/control/lifecycle.ts +30 -8
- package/lib/sandbox/control/protocol.ts +113 -0
- package/lib/sandbox/control/server.ts +431 -23
- package/lib/sandbox/control/state.ts +251 -1
- package/lib/server/process-state.ts +2 -2
- package/lib/server/protocol.ts +36 -1
- package/lib/task/activity-log.ts +8 -0
- package/lib/task/artifact-lifecycle.ts +34 -8
- package/lib/task/capabilities.ts +262 -0
- package/lib/task/commands/status.ts +38 -0
- package/lib/task/commit-intent.ts +137 -0
- package/lib/task/commit-operation.ts +186 -88
- package/lib/task/control-authority.ts +11 -8
- package/lib/task/create-service.ts +8 -8
- package/lib/task/create.ts +34 -9
- package/lib/task/current-contract.ts +6 -1
- package/lib/task/decision-details.ts +8 -64
- package/lib/task/delivery-target.ts +130 -0
- package/lib/task/delivery.ts +160 -0
- package/lib/task/events.ts +296 -16
- package/lib/task/finalization.ts +50 -14
- package/lib/task/human-override.ts +73 -46
- 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/lifecycle.ts +93 -4
- package/lib/task/local-artifact-finalization.ts +563 -0
- package/lib/task/orchestration.ts +110 -146
- package/lib/task/pr-delivery-fact.ts +237 -0
- package/lib/task/review-finalization.ts +4 -14
- package/lib/task/review-fingerprint.ts +33 -2
- package/lib/task/rework-intent.ts +165 -0
- package/lib/task/skill-scope.ts +24 -0
- package/lib/task/task-execution-lock.ts +23 -14
- package/lib/task/verification-engine.ts +95 -43
- package/lib/task/verification-review.ts +2 -0
- 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 +11 -1
- package/lib/version.ts +15 -1
- package/package.json +7 -1
- package/templates/.agents/rules/README.en.md +4 -2
- package/templates/.agents/rules/README.zh-CN.md +4 -2
- package/templates/.agents/rules/create-issue.en.md +11 -2
- package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
- package/templates/.agents/rules/issue-pr-commands.en.md +4 -17
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +28 -5
- package/templates/.agents/rules/issue-sync.zh-CN.md +64 -5
- package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
- package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
- package/templates/.agents/rules/local-artifact-repair.en.md +53 -0
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +53 -0
- package/templates/.agents/rules/milestone-inference.en.md +12 -2
- package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
- package/templates/.agents/rules/pr-sync.en.md +28 -13
- package/templates/.agents/rules/pr-sync.zh-CN.md +39 -5
- package/templates/.agents/rules/release-commands.en.md +42 -3
- package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
- package/templates/.agents/rules/security-alerts.en.md +17 -2
- package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
- package/templates/.agents/rules/sync-content-generation.en.md +8 -0
- package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
- package/templates/.agents/rules/task-management.en.md +1 -1
- package/templates/.agents/rules/task-management.zh-CN.md +1 -1
- 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/scripts/security-alerts.github.sh +151 -0
- package/templates/.agents/scripts/security-alerts.sh +31 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +14 -3
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -3
- 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 +32 -10
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +35 -13
- package/templates/.agents/skills/code-task/config/verify.en.json +1 -0
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/commit/SKILL.en.md +3 -3
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/config/verify.json +1 -1
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
- 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 +4 -4
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +4 -4
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -2
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +5 -4
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +5 -4
- package/templates/.agents/skills/complete-task/SKILL.en.md +31 -13
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +30 -13
- package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
- package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
- package/templates/.agents/skills/create-pr/SKILL.en.md +11 -10
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +11 -11
- 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 +1 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -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 +9 -10
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
- package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
- package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
- package/templates/.agents/skills/plan-task/SKILL.en.md +14 -3
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +11 -3
- package/templates/.agents/skills/review-analysis/SKILL.en.md +6 -5
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +6 -5
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +10 -9
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +10 -9
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
- package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
- package/templates/.agents/skills/review-plan/SKILL.en.md +6 -5
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +6 -5
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
- package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
- package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -2
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +4 -0
- package/templates/.agents/skills/watch-pr/SKILL.en.md +6 -6
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +6 -6
- 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 +23 -2
- package/templates/.agents/templates/task.zh-CN.md +23 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/feature-development.en.yaml +9 -8
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/refactoring.en.yaml +9 -8
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
- package/templates/.github/workflows/pr-label.yml +7 -26
- package/templates/.agents/rules/create-issue.github.en.md +0 -14
- package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
- package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
- package/templates/.agents/rules/issue-sync.github.en.md +0 -40
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
- package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
- package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
- package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
- package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
- package/templates/.agents/rules/pr-sync.github.en.md +0 -43
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
- package/templates/.agents/rules/release-commands.github.en.md +0 -44
- package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -44
- package/templates/.agents/rules/security-alerts.github.en.md +0 -43
- package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
- /package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +0 -0
- /package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +0 -0
|
@@ -7,6 +7,8 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
extractReviewBaseline,
|
|
10
|
+
extractReviewTargetHead,
|
|
11
|
+
extractReviewedHead,
|
|
10
12
|
extractReviewDiffBase,
|
|
11
13
|
extractReviewDiffFingerprint,
|
|
12
14
|
extractReviewedSnapshotTree,
|
|
@@ -30,6 +32,9 @@ import { inspectDecisionDetailDuplicates } from "./decision-details.ts";
|
|
|
30
32
|
import { loadVerificationConfig } from "./verification-config.ts";
|
|
31
33
|
import { snapshotReview } from "../git/review-snapshot.ts";
|
|
32
34
|
import { OrchestrationStateError, readRun } from "./orchestration.ts";
|
|
35
|
+
import { resolveDeliveryTarget } from "./delivery-target.ts";
|
|
36
|
+
import { readPrDeliveryFact } from "./pr-delivery-fact.ts";
|
|
37
|
+
import { validateLocalArtifact } from "./local-artifact-finalization.ts";
|
|
33
38
|
|
|
34
39
|
const TASK_ENUMS = {
|
|
35
40
|
type: ["feature", "bugfix", "refactor", "docs", "chore"],
|
|
@@ -84,7 +89,7 @@ let repoRoot = path.resolve(path.dirname(scriptPath), "..", "..");
|
|
|
84
89
|
|
|
85
90
|
const PLATFORM_ADAPTERS: Record<string, (context: any, shared: any) => any> = {
|
|
86
91
|
"platform-sync": checkPlatformSync,
|
|
87
|
-
"platform-sync-preflight": (context: any, shared: any) => ({ ...checkPlatformSync(context, shared), type: "platform-sync-preflight" }),
|
|
92
|
+
"platform-sync-preflight": async (context: any, shared: any) => ({ ...await checkPlatformSync(context, shared), type: "platform-sync-preflight" }),
|
|
88
93
|
"required-checks": checkRequiredChecks
|
|
89
94
|
};
|
|
90
95
|
const OPTIONAL_PLATFORM_CHECKS = new Set(["platform-sync"]);
|
|
@@ -103,7 +108,7 @@ const sharedUtils = {
|
|
|
103
108
|
parsePrNumber
|
|
104
109
|
};
|
|
105
110
|
|
|
106
|
-
function runCheck(type: any, context: any, shared: any): any {
|
|
111
|
+
async function runCheck(type: any, context: any, shared: any): Promise<any> {
|
|
107
112
|
switch (type) {
|
|
108
113
|
case "task-meta":
|
|
109
114
|
return checkTaskMeta(context);
|
|
@@ -143,7 +148,7 @@ function runCheck(type: any, context: any, shared: any): any {
|
|
|
143
148
|
return failResult(type, `Unsupported check type '${type}'.`);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
|
-
return adapter(context, shared);
|
|
151
|
+
return await adapter(context, shared);
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
}
|
|
@@ -195,15 +200,14 @@ function validateCleanCompletionEvidence(run: any): string | null {
|
|
|
195
200
|
|| !shaPattern.test(evidence.headTree)
|
|
196
201
|
|| !shaPattern.test(evidence.worktreeTree)
|
|
197
202
|
|| !shaPattern.test(evidence.lastReviewedCommit)
|
|
198
|
-
|| !Number.isInteger(evidence.prNumber)
|
|
199
|
-
|| evidence.
|
|
200
|
-
|| !shaPattern.test(evidence.prHead)
|
|
203
|
+
|| !(evidence.prNumber === null || (Number.isInteger(evidence.prNumber) && evidence.prNumber > 0))
|
|
204
|
+
|| !(evidence.prHead === null || shaPattern.test(evidence.prHead))
|
|
201
205
|
) {
|
|
202
206
|
return 'Clean completion evidence has an invalid structure';
|
|
203
207
|
}
|
|
204
208
|
if (
|
|
205
209
|
evidence.head !== evidence.lastReviewedCommit
|
|
206
|
-
|| evidence.head !== evidence.prHead
|
|
210
|
+
|| (evidence.prHead !== null && evidence.head !== evidence.prHead)
|
|
207
211
|
|| evidence.headTree !== evidence.worktreeTree
|
|
208
212
|
) {
|
|
209
213
|
return 'Clean completion evidence does not bind matching commit and tree identities';
|
|
@@ -276,12 +280,8 @@ function checkOrchestrationEvidence({ taskDir }: any): any {
|
|
|
276
280
|
if (run.completionEvidence != null) {
|
|
277
281
|
const evidenceError = validateCleanCompletionEvidence(run);
|
|
278
282
|
if (evidenceError) return failResult('orchestration-evidence', evidenceError);
|
|
279
|
-
} else if (run.status === 'completed'
|
|
280
|
-
|
|
281
|
-
|| run.receipts.at(-1)?.stage !== 'commit'
|
|
282
|
-
|| run.receipts.at(-1)?.status !== 'consumed'
|
|
283
|
-
)) {
|
|
284
|
-
return failResult('orchestration-evidence', 'Completed run requires a final consumed commit receipt');
|
|
283
|
+
} else if (run.status === 'completed') {
|
|
284
|
+
return failResult('orchestration-evidence', 'Completed run requires reviewed-head-clean completion evidence');
|
|
285
285
|
}
|
|
286
286
|
if (run.pendingDelegation && !['prepared', 'activated', 'stage-completed'].includes(run.pendingDelegation.status)) {
|
|
287
287
|
return failResult('orchestration-evidence', `Pending receipt has unsafe status '${run.pendingDelegation.status}'`);
|
|
@@ -489,7 +489,7 @@ function checkTaskMeta({ taskDir, config }: any): any {
|
|
|
489
489
|
);
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
-
function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
|
|
492
|
+
async function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): Promise<any> {
|
|
493
493
|
const task = loadTask(taskDir);
|
|
494
494
|
if (!task.ok) return failResult('required-pr-delivery', task.message);
|
|
495
495
|
let projectConfig: any = {};
|
|
@@ -500,23 +500,24 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
|
|
|
500
500
|
return failResult('required-pr-delivery', 'Project configuration is invalid');
|
|
501
501
|
}
|
|
502
502
|
const flow = projectConfig.prFlow;
|
|
503
|
-
const
|
|
504
|
-
|
|
503
|
+
const factRead = readPrDeliveryFact(task.metadata);
|
|
504
|
+
if (factRead.status === 'invalid') return failResult('required-pr-delivery', factRead.error.message);
|
|
505
|
+
const fact = factRead.status === 'valid' ? factRead.fact : null;
|
|
506
|
+
const status = fact?.state || 'unbound';
|
|
507
|
+
const prIdentity = fact?.state === 'bound' ? fact.identity.resource : null;
|
|
508
|
+
const prNumber = prIdentity?.kind === 'number' ? prIdentity.value : null;
|
|
505
509
|
if (flow === 'disabled') return passResult('required-pr-delivery', 'Pull request delivery is disabled by project policy');
|
|
506
|
-
if (flow === 'required' && (status !== '
|
|
510
|
+
if (flow === 'required' && (status !== 'bound' || !prIdentity)) {
|
|
507
511
|
return failResult('required-pr-delivery', 'Project policy requires a bound pull request before completion');
|
|
508
512
|
}
|
|
509
|
-
if (flow !== 'required' && status === '
|
|
513
|
+
if (flow !== 'required' && status === 'unbound') {
|
|
510
514
|
return failResult('required-pr-delivery', 'Pull request delivery is pending; create a PR or explicitly skip it');
|
|
511
515
|
}
|
|
512
|
-
if (status === 'created' && prNumber === null) {
|
|
513
|
-
return failResult('required-pr-delivery', 'Task claims a created pull request without a valid pr_number');
|
|
514
|
-
}
|
|
515
516
|
if (flow === 'required') {
|
|
516
517
|
if (mode === 'gate') {
|
|
517
518
|
return passResult('required-pr-delivery', 'Bound pull request shape is valid; merged-state inspection is reserved for hard preflight');
|
|
518
519
|
}
|
|
519
|
-
const inspected = inspectPlatformPullRequest(task.metadata.id, { cwd: repositoryRoot });
|
|
520
|
+
const inspected = await inspectPlatformPullRequest(task.metadata.id, { cwd: repositoryRoot });
|
|
520
521
|
if (inspected.status === 'blocked') {
|
|
521
522
|
return blockedResult(
|
|
522
523
|
'required-pr-delivery',
|
|
@@ -527,7 +528,8 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
|
|
|
527
528
|
const pullRequest = inspected.pullRequest;
|
|
528
529
|
const repository = inspected.platform.repository?.toLowerCase() || '';
|
|
529
530
|
const taskBranch = String(task.metadata.branch || '').trim();
|
|
530
|
-
|
|
531
|
+
const deliveryBaseRef = String(task.metadata.delivery_base_ref || projectConfig.delivery?.baseRef || '').trim();
|
|
532
|
+
if (inspected.status !== 'no-op' || !pullRequest) {
|
|
531
533
|
return failResult('required-pr-delivery', 'Bound pull request identity could not be verified');
|
|
532
534
|
}
|
|
533
535
|
if (
|
|
@@ -535,13 +537,14 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
|
|
|
535
537
|
|| pullRequest.repository.toLowerCase() !== repository
|
|
536
538
|
|| pullRequest.base.repository.toLowerCase() !== repository
|
|
537
539
|
|| (taskBranch && pullRequest.head.ref !== taskBranch)
|
|
540
|
+
|| (deliveryBaseRef && pullRequest.base.ref !== deliveryBaseRef)
|
|
538
541
|
) {
|
|
539
542
|
return failResult('required-pr-delivery', 'Bound pull request identity does not match the task');
|
|
540
543
|
}
|
|
541
544
|
if (pullRequest.state !== 'closed' || !pullRequest.mergedAt || !pullRequest.mergeCommitSha) {
|
|
542
545
|
return failResult('required-pr-delivery', 'Project policy requires the bound pull request to be merged');
|
|
543
546
|
}
|
|
544
|
-
return passResult('required-pr-delivery', `Pull request delivery policy satisfied (merged PR
|
|
547
|
+
return passResult('required-pr-delivery', `Pull request delivery policy satisfied (merged PR ${prNumber === null ? 'identity' : `#${prNumber}`})`);
|
|
545
548
|
}
|
|
546
549
|
return passResult('required-pr-delivery', `Pull request delivery policy satisfied (${status})`);
|
|
547
550
|
}
|
|
@@ -580,7 +583,7 @@ function loadProjectName(): any {
|
|
|
580
583
|
}
|
|
581
584
|
}
|
|
582
585
|
|
|
583
|
-
function checkArtifact({ taskDir, config, artifactFile }: any): any {
|
|
586
|
+
function checkArtifact({ taskDir, config, artifactFile, skillName }: any): any {
|
|
584
587
|
const resolvedArtifact = resolveArtifactPath(taskDir, config.file_pattern, artifactFile);
|
|
585
588
|
if (!resolvedArtifact.ok) {
|
|
586
589
|
return failResult("artifact", resolvedArtifact.message);
|
|
@@ -598,6 +601,26 @@ function checkArtifact({ taskDir, config, artifactFile }: any): any {
|
|
|
598
601
|
|
|
599
602
|
const content = fs.readFileSync(artifactPath, "utf8");
|
|
600
603
|
const requiredSections = config.required_sections || [];
|
|
604
|
+
const localFamily = skillName === "analyze-task"
|
|
605
|
+
? "analysis"
|
|
606
|
+
: skillName === "plan-task" ? "plan" : skillName === "code-task" ? "code" : null;
|
|
607
|
+
if (localFamily) {
|
|
608
|
+
const local = validateLocalArtifact(content, {
|
|
609
|
+
family: localFamily,
|
|
610
|
+
requiredSections: requiredSections.filter((section: unknown): section is string => typeof section === "string"),
|
|
611
|
+
requiredPatterns: (config.required_patterns || []).filter((pattern: unknown): pattern is string => typeof pattern === "string")
|
|
612
|
+
});
|
|
613
|
+
if (!local.ok) {
|
|
614
|
+
return failResult(
|
|
615
|
+
"artifact",
|
|
616
|
+
`${path.basename(artifactPath)} has local structural errors: ${local.diagnostics.map((item) => `${item.code}: ${item.message}`).join('; ')}`
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
return passResult(
|
|
620
|
+
"artifact",
|
|
621
|
+
`${path.basename(artifactPath)} passed (${requiredSections.length} sections)`
|
|
622
|
+
);
|
|
623
|
+
}
|
|
601
624
|
const missingSections = requiredSections.filter(
|
|
602
625
|
(section: any) => !new RegExp(`^##\\s+${escapeRegExp(section)}\\s*$`, "m").test(content)
|
|
603
626
|
);
|
|
@@ -1030,6 +1053,7 @@ function checkManualValidation({ taskDir }: any): any {
|
|
|
1030
1053
|
// 1. Latest review-code artifact; none -> pass (no review, check not applicable).
|
|
1031
1054
|
const review = findAuthoritativeReviewCodeArtifact(taskDir);
|
|
1032
1055
|
if (!review.ok) {
|
|
1056
|
+
if (review.error) return failResult("manual-validation", `Review-code artifact is unavailable: ${review.error}`);
|
|
1033
1057
|
return passResult("manual-validation", "No review-code artifact; manual validation not applicable");
|
|
1034
1058
|
}
|
|
1035
1059
|
// 2. Parse the numeric manual-validation count; unparseable/null -> fail closed
|
|
@@ -1095,9 +1119,10 @@ function checkManualValidation({ taskDir }: any): any {
|
|
|
1095
1119
|
return passResult("manual-validation", `Manual validation completed → ${artifactName}`);
|
|
1096
1120
|
}
|
|
1097
1121
|
|
|
1098
|
-
function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
1122
|
+
async function checkPostReviewCommit({ taskDir, config }: any): Promise<any> {
|
|
1099
1123
|
const reviewArtifact = findAuthoritativeReviewCodeArtifact(taskDir);
|
|
1100
1124
|
if (!reviewArtifact.ok) {
|
|
1125
|
+
if (reviewArtifact.error) return failResult("post-review-commit", `Review-code artifact is unavailable: ${reviewArtifact.error}`);
|
|
1101
1126
|
return passResult("post-review-commit", "No review-code artifact; check inactive");
|
|
1102
1127
|
}
|
|
1103
1128
|
|
|
@@ -1110,12 +1135,15 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
1110
1135
|
|
|
1111
1136
|
const task = loadTask(taskDir);
|
|
1112
1137
|
if (!task.ok) return failResult("post-review-commit", task.message);
|
|
1138
|
+
const factRead = readPrDeliveryFact(task.metadata);
|
|
1139
|
+
if (factRead.status === 'invalid') return failResult("post-review-commit", factRead.error.message);
|
|
1140
|
+
const fact = factRead.status === 'valid' ? factRead.fact : null;
|
|
1113
1141
|
const lastReviewedCommit = task.ok ? (task.metadata.last_reviewed_commit || "").trim() : "";
|
|
1114
1142
|
const globs = resolvePostReviewGlobs(config, loadPostReviewConfig(repoRoot));
|
|
1115
|
-
const hasPullRequest =
|
|
1116
|
-
let inspected: ReturnType<typeof inspectPlatformPullRequest
|
|
1143
|
+
const hasPullRequest = fact?.state === 'bound';
|
|
1144
|
+
let inspected: Awaited<ReturnType<typeof inspectPlatformPullRequest>> | null = null;
|
|
1117
1145
|
if (hasPullRequest) {
|
|
1118
|
-
inspected = inspectPlatformPullRequest(task.metadata.id, { cwd: gitRoot });
|
|
1146
|
+
inspected = await inspectPlatformPullRequest(task.metadata.id, { cwd: gitRoot });
|
|
1119
1147
|
if (!inspected.pullRequest) {
|
|
1120
1148
|
const message = inspected.error?.message || "PR merge snapshot is unavailable";
|
|
1121
1149
|
const code = inspected.error?.code || "PR_INSPECTION_INVALID";
|
|
@@ -1128,7 +1156,7 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
1128
1156
|
inspected.pullRequest.mergedAt &&
|
|
1129
1157
|
inspected.pullRequest.mergeCommitSha
|
|
1130
1158
|
) {
|
|
1131
|
-
const relation = resolveMaterializedReviewedHeadRelation({
|
|
1159
|
+
const relation = await resolveMaterializedReviewedHeadRelation({
|
|
1132
1160
|
cwd: gitRoot,
|
|
1133
1161
|
platformType: inspected.platform.type,
|
|
1134
1162
|
lastReviewedCommit,
|
|
@@ -1295,6 +1323,17 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
1295
1323
|
return failResult("review-fact", resolvedArtifact.message);
|
|
1296
1324
|
}
|
|
1297
1325
|
|
|
1326
|
+
const authoritative = findAuthoritativeReviewCodeArtifact(taskDir);
|
|
1327
|
+
if (!authoritative.ok) {
|
|
1328
|
+
return failResult("review-fact", authoritative.error ?? "No active review-code artifact is available");
|
|
1329
|
+
}
|
|
1330
|
+
if (path.basename(resolvedArtifact.path) !== authoritative.fileName) {
|
|
1331
|
+
return failResult(
|
|
1332
|
+
"review-fact",
|
|
1333
|
+
`review-code artifact ${path.basename(resolvedArtifact.path)} is not the current active artifact ${authoritative.fileName}; re-run review-code`
|
|
1334
|
+
);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1298
1337
|
const task = loadTask(taskDir);
|
|
1299
1338
|
if (!task.ok) {
|
|
1300
1339
|
return failResult("review-fact", task.message);
|
|
@@ -1302,7 +1341,8 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
1302
1341
|
|
|
1303
1342
|
const content = fs.readFileSync(resolvedArtifact.path, "utf8");
|
|
1304
1343
|
const verdict = parseReviewVerdict(content);
|
|
1305
|
-
const
|
|
1344
|
+
const reviewTargetHead = extractReviewTargetHead(content);
|
|
1345
|
+
const reviewReviewedHead = extractReviewedHead(content);
|
|
1306
1346
|
const reviewDiffBase = extractReviewDiffBase(content);
|
|
1307
1347
|
const reviewedFingerprint = extractReviewDiffFingerprint(content);
|
|
1308
1348
|
const reviewedTree = extractReviewedSnapshotTree(content);
|
|
@@ -1311,30 +1351,42 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
1311
1351
|
return failResult("review-fact", `Unsupported review verdict '${verdict}'`);
|
|
1312
1352
|
}
|
|
1313
1353
|
|
|
1354
|
+
const deliveryRemote = String(task.metadata.delivery_remote || "").trim();
|
|
1355
|
+
const deliveryBaseRef = String(task.metadata.delivery_base_ref || "").trim();
|
|
1356
|
+
if (!deliveryRemote || !deliveryBaseRef) {
|
|
1357
|
+
return failResult("review-fact", "Task delivery target is not bound; re-run task branch preparation before review-code");
|
|
1358
|
+
}
|
|
1359
|
+
if (!reviewTargetHead || !reviewReviewedHead || !reviewDiffBase) {
|
|
1360
|
+
return failResult("review-fact", "Review fact must record target head, reviewed head, and diff base");
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1314
1363
|
let gitRoot;
|
|
1315
1364
|
let head;
|
|
1316
1365
|
let baseline;
|
|
1366
|
+
let targetHead;
|
|
1317
1367
|
let diffBase;
|
|
1318
1368
|
try {
|
|
1319
1369
|
gitRoot = execFileSync("git", ["-C", taskDir, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
|
|
1320
1370
|
head = execFileSync("git", ["-C", gitRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
).trim();
|
|
1371
|
+
const target = resolveDeliveryTarget(gitRoot, { remote: deliveryRemote, baseRef: deliveryBaseRef });
|
|
1372
|
+
if (!target.ok) throw new Error(target.message);
|
|
1373
|
+
const reviewedRef = reviewReviewedHead;
|
|
1374
|
+
baseline = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewedRef}^{commit}`], { encoding: "utf8" }).trim();
|
|
1375
|
+
targetHead = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewTargetHead}^{commit}`], { encoding: "utf8" }).trim();
|
|
1376
|
+
const computed = execFileSync("git", ["-C", gitRoot, "merge-base", baseline, targetHead], { encoding: "utf8" }).trim();
|
|
1377
|
+
diffBase = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewDiffBase}^{commit}`], { encoding: "utf8" }).trim();
|
|
1378
|
+
if (diffBase !== computed) throw new Error('saved review diff base does not match merge-base(reviewed head, target head)');
|
|
1327
1379
|
} catch {
|
|
1328
1380
|
return blockedResult(
|
|
1329
1381
|
"review-fact",
|
|
1330
|
-
`Unable to resolve review
|
|
1382
|
+
`Unable to resolve saved review commits in the task repository; re-run review-code`
|
|
1331
1383
|
);
|
|
1332
1384
|
}
|
|
1333
1385
|
|
|
1334
1386
|
if (baseline !== head) {
|
|
1335
1387
|
return failResult(
|
|
1336
1388
|
"review-fact",
|
|
1337
|
-
`
|
|
1389
|
+
`Reviewed head ${baseline.slice(0, 8)} does not match current HEAD ${head.slice(0, 8)}; re-run review-code`
|
|
1338
1390
|
);
|
|
1339
1391
|
}
|
|
1340
1392
|
|
|
@@ -1378,7 +1430,7 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
1378
1430
|
if (cleanSnapshot && lastReviewedCommit !== baseline) {
|
|
1379
1431
|
return failResult(
|
|
1380
1432
|
"review-fact",
|
|
1381
|
-
`Approved clean review must set task last_reviewed_commit to
|
|
1433
|
+
`Approved clean review must set task last_reviewed_commit to reviewed head ${baseline.slice(0, 8)}`
|
|
1382
1434
|
);
|
|
1383
1435
|
}
|
|
1384
1436
|
if (!cleanSnapshot && lastReviewedCommit) {
|
|
@@ -1638,7 +1690,7 @@ function isBlank(value: any): any {
|
|
|
1638
1690
|
return value === undefined || value === null || String(value).trim() === "";
|
|
1639
1691
|
}
|
|
1640
1692
|
|
|
1641
|
-
function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: requestedChecks, repositoryRoot }: any): any {
|
|
1693
|
+
async function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: requestedChecks, repositoryRoot }: any): Promise<any> {
|
|
1642
1694
|
if (repositoryRoot) repoRoot = path.resolve(repositoryRoot);
|
|
1643
1695
|
else {
|
|
1644
1696
|
let cursor = path.resolve(taskDir);
|
|
@@ -1651,7 +1703,7 @@ function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: reque
|
|
|
1651
1703
|
const checks = [];
|
|
1652
1704
|
for (const [type, checkConfig] of Object.entries(verifyConfig.checks || {})) {
|
|
1653
1705
|
if (checkConfig === null) continue;
|
|
1654
|
-
const result = runCheck(type, {
|
|
1706
|
+
const result = await runCheck(type, {
|
|
1655
1707
|
mode,
|
|
1656
1708
|
skillName,
|
|
1657
1709
|
taskDir: path.resolve(taskDir),
|
|
@@ -1671,7 +1723,7 @@ function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: reque
|
|
|
1671
1723
|
if (config === null) return { skill: skillName, ...passResult(type, `Check '${type}' is disabled for skill '${skillName}'.`) };
|
|
1672
1724
|
return {
|
|
1673
1725
|
skill: skillName,
|
|
1674
|
-
...runCheck(type, {
|
|
1726
|
+
...await runCheck(type, {
|
|
1675
1727
|
skillName,
|
|
1676
1728
|
taskDir: path.resolve(taskDir),
|
|
1677
1729
|
artifactFile,
|
package/lib/task/verification.ts
CHANGED
|
@@ -49,7 +49,7 @@ type TaskVerificationResult = {
|
|
|
49
49
|
};
|
|
50
50
|
type VerificationOptions = {
|
|
51
51
|
repoRoot?: string;
|
|
52
|
-
engine?: typeof verifyInProcess
|
|
52
|
+
engine?: (input: Parameters<typeof verifyInProcess>[0]) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
53
53
|
manualOverride?: ManualOverrideCapability;
|
|
54
54
|
};
|
|
55
55
|
|
|
@@ -91,7 +91,7 @@ function failure(request: { taskRef: string; event: string; artifact?: string },
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: string }, options: VerificationOptions = {}): TaskVerificationResult {
|
|
94
|
+
async function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: string }, options: VerificationOptions = {}): Promise<TaskVerificationResult> {
|
|
95
95
|
const spec = VERIFICATION_CATALOG[request.event as VerificationEvent];
|
|
96
96
|
if (!spec) return failure(request, 'VERIFY_EVENT_UNKNOWN', `unknown verification event '${request.event}'`);
|
|
97
97
|
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
@@ -113,7 +113,7 @@ function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: s
|
|
|
113
113
|
const invocations: VerificationInvocation[] = [];
|
|
114
114
|
const engine = options.engine ?? verifyInProcess;
|
|
115
115
|
if (spec.mode === 'gate') {
|
|
116
|
-
const payload = engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot })
|
|
116
|
+
const payload = await engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot });
|
|
117
117
|
const status = payload.gate as 'pass' | 'fail' | 'blocked';
|
|
118
118
|
if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
|
|
119
119
|
invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, gate: 'pass', humanOverride: 'human-approved', originalGate: status } });
|
|
@@ -125,7 +125,7 @@ function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: s
|
|
|
125
125
|
invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
|
|
126
126
|
} else {
|
|
127
127
|
for (const check of spec.checks ?? []) {
|
|
128
|
-
const payload = engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot })
|
|
128
|
+
const payload = await engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot });
|
|
129
129
|
const status = payload.status as 'pass' | 'fail' | 'blocked';
|
|
130
130
|
if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
|
|
131
131
|
invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, status: 'pass', humanOverride: 'human-approved', originalStatus: status } });
|
|
@@ -68,7 +68,7 @@ function sectionMutation(content: string): TaskMutation[] {
|
|
|
68
68
|
const english = /^##\s+Activity Log\s*$/m.test(content);
|
|
69
69
|
return [{
|
|
70
70
|
kind: 'section', aliases: WORKFLOW_WARNING_HEADINGS, heading: english ? 'Workflow Warnings' : '工作流告警',
|
|
71
|
-
body: `| ${WORKFLOW_WARNING_COLUMNS.join(' | ')} |\n
|
|
71
|
+
body: `| ${WORKFLOW_WARNING_COLUMNS.join(' | ')} |\n|----|------|------|----------|------|--------|---------|--------|-------------|------------|------------|`
|
|
72
72
|
}];
|
|
73
73
|
}
|
|
74
74
|
|
package/lib/task/write.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { allowsManualOverride } from './guard-override.ts';
|
|
|
16
16
|
import type { ManualOverrideCapability } from './guard-override.ts';
|
|
17
17
|
import { mutateTableRow, upsertSection } from './sections.ts';
|
|
18
18
|
import { validateCurrentTaskContract } from './current-contract.ts';
|
|
19
|
+
import { invalidationBlocks, parseInvalidationDocument } from './invalidation.ts';
|
|
19
20
|
import type {
|
|
20
21
|
TableRowDeleteMutation,
|
|
21
22
|
TableRowUpsertMutation
|
|
@@ -86,6 +87,8 @@ type TaskWriteErrorCode =
|
|
|
86
87
|
| ResolveTaskRefErrorCode
|
|
87
88
|
| 'TASK_STATE_MISMATCH'
|
|
88
89
|
| 'TASK_CURRENT_CONTRACT_INVALID'
|
|
90
|
+
| 'TASK_INVALIDATION_INVALID'
|
|
91
|
+
| 'TASK_INVALIDATION_BLOCKED'
|
|
89
92
|
| 'TASK_READ_FAILED'
|
|
90
93
|
| 'TASK_DOCUMENT_INVALID'
|
|
91
94
|
| 'MUTATION_INVALID'
|
|
@@ -161,6 +164,7 @@ type TaskWriteOptions = {
|
|
|
161
164
|
randomSuffix?: () => string;
|
|
162
165
|
fileSystem?: Partial<TaskFileSystem>;
|
|
163
166
|
manualOverride?: ManualOverrideCapability;
|
|
167
|
+
invalidationContext?: 'standard' | 'source-completion' | 'reconcile';
|
|
164
168
|
};
|
|
165
169
|
|
|
166
170
|
const DEFAULT_FILE_SYSTEM: TaskFileSystem = {
|
|
@@ -275,6 +279,21 @@ function writeTask(request: TaskWriteRequest, options: TaskWriteOptions = {}): T
|
|
|
275
279
|
if (!contract.ok) {
|
|
276
280
|
return failure(request, identity, contract.code, contract.message);
|
|
277
281
|
}
|
|
282
|
+
if (
|
|
283
|
+
invalidationBlocks(contract.invalidation)
|
|
284
|
+
&& options.invalidationContext !== 'source-completion'
|
|
285
|
+
&& options.invalidationContext !== 'reconcile'
|
|
286
|
+
) {
|
|
287
|
+
return failure(
|
|
288
|
+
request,
|
|
289
|
+
identity,
|
|
290
|
+
'TASK_INVALIDATION_BLOCKED',
|
|
291
|
+
'task has an incomplete artifact invalidation operation; reconcile it before writing downstream state'
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
} else {
|
|
295
|
+
const invalidation = parseInvalidationDocument(original);
|
|
296
|
+
if (!invalidation.ok) return failure(request, identity, 'TASK_INVALIDATION_INVALID', invalidation.message);
|
|
278
297
|
}
|
|
279
298
|
|
|
280
299
|
let candidate = original;
|
package/lib/update.ts
CHANGED
|
@@ -19,10 +19,11 @@ type UpdateConfig = {
|
|
|
19
19
|
project: string;
|
|
20
20
|
org: string;
|
|
21
21
|
language: string;
|
|
22
|
-
platform?: { type?: string };
|
|
22
|
+
platform?: { type?: string; providers?: Record<string, unknown> };
|
|
23
23
|
prFlow?: 'required' | 'disabled';
|
|
24
24
|
sandbox?: Record<string, unknown>;
|
|
25
25
|
task?: { shortIdLength: number };
|
|
26
|
+
delivery?: { remote?: string; baseRef?: string };
|
|
26
27
|
labels?: Record<string, unknown>;
|
|
27
28
|
files?: Partial<FileRegistry>;
|
|
28
29
|
agentClients?: unknown;
|
|
@@ -33,6 +34,7 @@ type Defaults = {
|
|
|
33
34
|
platform: { type: string };
|
|
34
35
|
sandbox: Record<string, unknown>;
|
|
35
36
|
task: { shortIdLength: number };
|
|
37
|
+
delivery: { remote: string; baseRef: string };
|
|
36
38
|
labels: Record<string, unknown>;
|
|
37
39
|
files: FileRegistry;
|
|
38
40
|
};
|
|
@@ -83,10 +85,12 @@ async function cmdSync(): Promise<void> {
|
|
|
83
85
|
const sandboxAdded = !config.sandbox;
|
|
84
86
|
const taskAdded = !config.task;
|
|
85
87
|
const labelsAdded = !config.labels;
|
|
88
|
+
const deliveryAdded = !config.delivery;
|
|
86
89
|
if (platformAdded) config.platform = structuredClone(defaults.platform);
|
|
87
90
|
if (sandboxAdded) config.sandbox = structuredClone(defaults.sandbox);
|
|
88
91
|
if (taskAdded) config.task = structuredClone(defaults.task);
|
|
89
92
|
if (labelsAdded) config.labels = structuredClone(defaults.labels);
|
|
93
|
+
if (deliveryAdded) config.delivery = structuredClone(defaults.delivery);
|
|
90
94
|
|
|
91
95
|
const workflowPlan = planAgentClientReconciliation({
|
|
92
96
|
config: config as unknown as Record<string, unknown>,
|
|
@@ -150,6 +154,9 @@ async function cmdSync(): Promise<void> {
|
|
|
150
154
|
if (labelsAdded) {
|
|
151
155
|
info(`Default labels.in config added to ${CONFIG_PATH}.`);
|
|
152
156
|
}
|
|
157
|
+
if (deliveryAdded) {
|
|
158
|
+
info(`Default delivery target added to ${CONFIG_PATH}.`);
|
|
159
|
+
}
|
|
153
160
|
} else {
|
|
154
161
|
info(`File registry changed in ${CONFIG_PATH}.`);
|
|
155
162
|
}
|
|
@@ -165,6 +172,9 @@ async function cmdSync(): Promise<void> {
|
|
|
165
172
|
if (hasNewEntries && platformAdded) {
|
|
166
173
|
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
167
174
|
}
|
|
175
|
+
if (hasNewEntries && deliveryAdded) {
|
|
176
|
+
info(`Default delivery target added to ${CONFIG_PATH}.`);
|
|
177
|
+
}
|
|
168
178
|
ok(`Updated ${CONFIG_PATH}`);
|
|
169
179
|
}
|
|
170
180
|
|
package/lib/version.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import semver from 'semver';
|
|
2
3
|
|
|
3
4
|
const packageJsonUrl = [
|
|
4
5
|
new URL('../package.json', import.meta.url),
|
|
@@ -12,9 +13,22 @@ if (!packageJsonUrl) {
|
|
|
12
13
|
const { version } = JSON.parse(readFileSync(packageJsonUrl, 'utf8'));
|
|
13
14
|
const VERSION = `v${version}`;
|
|
14
15
|
const AGENT_INFRA_VERSION_PATTERN = /^v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
16
|
+
const LEGACY_COMPATIBILITY_CUTOFF_VERSION = '1.0.0';
|
|
15
17
|
|
|
16
18
|
function isValidAgentInfraVersion(value: unknown): value is string {
|
|
17
19
|
return typeof value === 'string' && AGENT_INFRA_VERSION_PATTERN.test(value);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
function isLegacyCompatibilityEnabled(runtimeVersion = VERSION): boolean {
|
|
23
|
+
const normalized = runtimeVersion.startsWith('v') ? runtimeVersion.slice(1) : runtimeVersion;
|
|
24
|
+
const parsed = semver.valid(normalized);
|
|
25
|
+
return parsed !== null && semver.lt(parsed, LEGACY_COMPATIBILITY_CUTOFF_VERSION);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function legacyCompatibilityError(resource: string, runtimeVersion = VERSION): Error & { code: string } {
|
|
29
|
+
return Object.assign(new Error(
|
|
30
|
+
`PLATFORM_IDENTITY_LEGACY_UNSUPPORTED: ${resource} requires migration to the current schema before v${LEGACY_COMPATIBILITY_CUTOFF_VERSION} runtime ${runtimeVersion}`
|
|
31
|
+
), { code: 'PLATFORM_IDENTITY_LEGACY_UNSUPPORTED' });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { LEGACY_COMPATIBILITY_CUTOFF_VERSION, VERSION, isLegacyCompatibilityEnabled, isValidAgentInfraVersion, legacyCompatibilityError };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fitlab-ai/agent-infra",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Antigravity CLI, and OpenCode",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
"access": "public",
|
|
18
18
|
"registry": "https://registry.npmjs.org/"
|
|
19
19
|
},
|
|
20
|
+
"exports": {
|
|
21
|
+
"./platform-provider": {
|
|
22
|
+
"types": "./dist/lib/platform/provider-contract.d.ts",
|
|
23
|
+
"import": "./dist/lib/platform/provider-contract.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
20
26
|
"bin": {
|
|
21
27
|
"agent-infra": "./dist/bin/cli.js",
|
|
22
28
|
"ai": "./dist/bin/cli.js",
|
|
@@ -13,6 +13,7 @@ so you can quickly find "which ones to read" without opening each file.
|
|
|
13
13
|
- [`version-stamp.md`](version-stamp.md) — How and when to stamp `agent_infra_version`.
|
|
14
14
|
- [`debugging-guide.md`](debugging-guide.md) — Structured debugging flow: gather evidence → form hypothesis → verify hypothesis → fix the root cause; no blind patch-and-retry.
|
|
15
15
|
- [`compatibility-policy.md`](compatibility-policy.md) — Compatibility by exception: admission evidence, implementation boundaries, exit conditions, and lifecycle review requirements.
|
|
16
|
+
- [`sync-content-generation.md`](sync-content-generation.md) — Producer-side Markdown constraints for task and lifecycle content synchronized to Issues.
|
|
16
17
|
|
|
17
18
|
## Issue / PR
|
|
18
19
|
|
|
@@ -29,11 +30,12 @@ so you can quickly find "which ones to read" without opening each file.
|
|
|
29
30
|
- [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — Fresh executor/reviewer, one-use receipt, pause/recovery, and safe endpoint rules for `run-task`.
|
|
30
31
|
- [`review-handshake.md`](review-handshake.md) — Three-stage bidirectional review handshake: four-state disposition, symmetric evidence, disagreement ledger, convergence and post-review commit gate.
|
|
31
32
|
- [`review-method.md`](review-method.md) — Shared three-stage review method: multi-pass review, risk lenses, traceability, and finding evidence.
|
|
33
|
+
- [`local-artifact-repair.md`](local-artifact-repair.md) — Pre-completion local artifact validation for analysis/plan/code and model-per-case repair, safety gates, and convergence for failed review artifacts.
|
|
32
34
|
- [`human-decision-context.md`](human-decision-context.md) — Self-contained context and canonical structure for new human-decision details.
|
|
33
35
|
- [`task-short-id.md`](task-short-id.md) — Resolution, allocation and lifecycle of bare-number short ids.
|
|
34
36
|
- [`milestone-inference.md`](milestone-inference.md) — Milestone inference for create-task / code-task / create-pr.
|
|
35
|
-
- [`label-milestone-setup.md`](label-milestone-setup.md) —
|
|
36
|
-
- [`security-alerts.md`](security-alerts.md) —
|
|
37
|
+
- [`label-milestone-setup.md`](label-milestone-setup.md) — Shared entry points to initialize labels / milestones.
|
|
38
|
+
- [`security-alerts.md`](security-alerts.md) — Shared entry point to import / close dependency and code-scanning alerts.
|
|
37
39
|
|
|
38
40
|
## Commit & Release
|
|
39
41
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [`version-stamp.md`](version-stamp.md) — `agent_infra_version` 版本戳的取值命令与写入时机。
|
|
13
13
|
- [`debugging-guide.md`](debugging-guide.md) — 结构化调试流程:收集证据→形成假设→验证假设→修复根因,禁止盲目改代码重试。
|
|
14
14
|
- [`compatibility-policy.md`](compatibility-policy.md) — 兼容性默认关闭:准入证据、实现边界、退出条件与生命周期审查要求。
|
|
15
|
+
- [`sync-content-generation.md`](sync-content-generation.md) — 同步到 Issue 的任务和生命周期 Markdown 生成约束。
|
|
15
16
|
|
|
16
17
|
## Issue / PR
|
|
17
18
|
|
|
@@ -28,11 +29,12 @@
|
|
|
28
29
|
- [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — `run-task` 的 fresh executor/reviewer、一次性 receipt、暂停恢复与安全终点规则。
|
|
29
30
|
- [`review-handshake.md`](review-handshake.md) — 三阶段双向审查握手协议:四态处置、对称证据、分歧账本、收敛与 post-review commit 门禁。
|
|
30
31
|
- [`review-method.md`](review-method.md) — 三阶段共享检视方法:多遍检视、风险镜头、追踪与 finding 证据契约。
|
|
32
|
+
- [`local-artifact-repair.md`](local-artifact-repair.md) — analysis/plan/code completed 前的本地产物校验、review artifact 失败后的模型逐例修复、机械安全门与收敛契约。
|
|
31
33
|
- [`human-decision-context.md`](human-decision-context.md) — 新建人工裁决详情的自足上下文与规范结构。
|
|
32
34
|
- [`task-short-id.md`](task-short-id.md) — 裸数字任务短号的解析、分配与生命周期。
|
|
33
35
|
- [`milestone-inference.md`](milestone-inference.md) — create-task / code-task / create-pr 的 milestone 推断。
|
|
34
|
-
- [`label-milestone-setup.md`](label-milestone-setup.md) — 初始化 label / milestone
|
|
35
|
-
- [`security-alerts.md`](security-alerts.md) — 导入 /
|
|
36
|
+
- [`label-milestone-setup.md`](label-milestone-setup.md) — 初始化 label / milestone 的共享入口。
|
|
37
|
+
- [`security-alerts.md`](security-alerts.md) — 导入 / 关闭依赖与代码扫描告警的共享入口。
|
|
36
38
|
|
|
37
39
|
## 提交与发布
|
|
38
40
|
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Issue Creation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> `--agent` values are defined in `.agents/rules/task-management.md` under “Collaborator Token Specification”.
|
|
4
4
|
|
|
5
|
-
`create-task`
|
|
5
|
+
After `create-task` writes task.md, create and initialize the Issue through declarative internal intents:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
agent-infra-internal platform-issue create {task-id} --agent {standard-agent-token}
|
|
9
|
+
agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status waiting-for-triage --assignees current --milestone initial --issue-type --fields
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The core reads only persisted task identity, title, type, description, and requirements, and reuses deterministic `ai task issue-body` rendering. It owns template selection, upstream/capabilities, duplicate prevention, POST outcome boundaries, response validation, and atomic `issue_number` binding.
|
|
13
|
+
|
|
14
|
+
`planned|applied|no-op|degraded` exit 0, `failed` exits 1, and `blocked` exits 2. Callers must not fall back to direct platform CLI or GraphQL orchestration.
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Issue 创建
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> `--agent` 取值见 `.agents/rules/task-management.md`「合作者 token 规范」。
|
|
4
4
|
|
|
5
|
-
`create-task`
|
|
5
|
+
当 `create-task` 完成本地 `task.md` 落盘后,通过声明式内部命令创建 Issue:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
agent-infra-internal platform-issue create {task-id} --agent {standard-agent-token}
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
命令只从已落盘 task.md 读取身份、标题、类型、描述与需求,并复用 `ai task issue-body` 的确定性正文渲染。它负责模板选择、upstream/capability、已有绑定检查、非幂等 POST 边界、响应身份校验及通过任务写入内核回写 `issue_number`。
|
|
12
|
+
|
|
13
|
+
创建后的初始元数据使用同一适配层同步:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} \
|
|
17
|
+
--status waiting-for-triage --assignees current --milestone initial --issue-type --fields
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 结果处理
|
|
21
|
+
|
|
22
|
+
- `planned|applied|no-op|degraded`:exit 0;调用方按 operations 继续评论同步。
|
|
23
|
+
- `failed`:exit 1;调用方登记 `ISSUE_CREATE_FAILED` warning,不伪造绑定。
|
|
24
|
+
- `blocked`:exit 2;认证、网络或创建 outcome 不确定,调用方保留远端 identity 证据并停止盲目重试。
|
|
25
|
+
- 已绑定有效 Issue 时只验证绑定并返回 no-op,绝不重复创建。
|
|
26
|
+
|
|
27
|
+
自定义或空平台返回 no-op/degraded;调用方不得回退到直接平台 CLI 或 GraphQL 编排。
|