@fitlab-ai/agent-infra 0.11.3 → 0.11.5
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 +17 -8
- package/README.zh-CN.md +17 -8
- package/dist/bin/internal-cli.js +1 -6
- package/dist/lib/decide.js +4 -41
- package/dist/lib/git/branch-worktree.js +45 -0
- package/dist/lib/internal/cli-route-inventory.js +1 -4
- package/dist/lib/internal/task-activity.js +7 -40
- package/dist/lib/internal/task-artifact.js +1 -1
- package/dist/lib/internal/task-event.js +4 -37
- package/dist/lib/internal/task-finalization.js +48 -1
- package/dist/lib/internal/task-ledger.js +14 -44
- package/dist/lib/internal/task-lifecycle.js +1 -1
- package/dist/lib/internal/task-operation-registry.js +2 -4
- package/dist/lib/internal/task-review.js +5 -37
- package/dist/lib/internal/task-verify.js +3 -47
- package/dist/lib/internal/task-warning.js +4 -40
- package/dist/lib/platform/completion-backfill.js +63 -17
- package/dist/lib/platform/pr-summary.js +4 -23
- package/dist/lib/platform/verification-sync.js +12 -49
- package/dist/lib/sandbox/control/client.js +4 -1
- package/dist/lib/sandbox/control/executor.js +12 -4
- package/dist/lib/sandbox/control/protocol.js +2 -1
- package/dist/lib/sandbox/control/server.js +26 -143
- package/dist/lib/sandbox/removal.js +15 -8
- package/dist/lib/sandbox/task-cleanup.js +13 -20
- package/dist/lib/task/activity-intent.js +1 -2
- package/dist/lib/task/artifact-command.js +11 -4
- package/dist/lib/task/artifact-lifecycle.js +217 -85
- package/dist/lib/task/artifact-operations.js +37 -28
- package/dist/lib/task/artifact-receipts.js +4 -1
- package/dist/lib/task/artifact-schema.js +8 -7
- package/dist/lib/task/artifact-selection.js +25 -0
- package/dist/lib/task/capabilities.js +158 -39
- package/dist/lib/task/commands/status.js +9 -2
- package/dist/lib/task/control-authority.js +12 -168
- package/dist/lib/task/decision-intents.js +14 -4
- package/dist/lib/task/delivery.js +1 -43
- package/dist/lib/task/events.js +68 -73
- package/dist/lib/task/finalization-handoff.js +92 -0
- package/dist/lib/task/finalization.js +423 -154
- package/dist/lib/task/intermediate-cleanup.js +9 -148
- package/dist/lib/task/ledger-intents.js +159 -20
- package/dist/lib/task/lifecycle-path.js +75 -0
- package/dist/lib/task/lifecycle.js +60 -11
- package/dist/lib/task/local-artifact-finalization.js +13 -47
- package/dist/lib/task/orchestration.js +17 -7
- package/dist/lib/task/review-command.js +1 -2
- package/dist/lib/task/review-finalization.js +4 -18
- package/dist/lib/task/rework-intent.js +70 -4
- package/dist/lib/task/snapshot.js +6 -6
- package/dist/lib/task/verification-engine.js +25 -30
- package/dist/lib/task/verification.js +2 -13
- package/dist/lib/task/workflow-warning-intents.js +23 -10
- package/dist/lib/task/workspace-snapshot.js +7 -2
- package/dist/lib/task/write.js +1 -2
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/decide.ts +5 -35
- package/lib/git/branch-worktree.ts +41 -0
- package/lib/internal/cli-route-inventory.ts +1 -3
- package/lib/internal/task-activity.ts +6 -34
- package/lib/internal/task-artifact.ts +1 -1
- package/lib/internal/task-event.ts +4 -37
- package/lib/internal/task-finalization.ts +47 -1
- package/lib/internal/task-ledger.ts +15 -41
- package/lib/internal/task-lifecycle.ts +2 -2
- package/lib/internal/task-operation-registry.ts +2 -4
- package/lib/internal/task-review.ts +5 -31
- package/lib/internal/task-verify.ts +3 -39
- package/lib/internal/task-warning.ts +3 -32
- package/lib/platform/completion-backfill.ts +78 -16
- package/lib/platform/pr-summary.ts +4 -25
- package/lib/platform/verification-sync.ts +13 -53
- package/lib/sandbox/control/client.ts +5 -1
- package/lib/sandbox/control/executor.ts +13 -4
- package/lib/sandbox/control/protocol.ts +3 -2
- package/lib/sandbox/control/server.ts +21 -146
- package/lib/sandbox/removal.ts +23 -7
- package/lib/sandbox/task-cleanup.ts +12 -20
- package/lib/task/activity-intent.ts +1 -2
- package/lib/task/artifact-command.ts +14 -4
- package/lib/task/artifact-lifecycle.ts +236 -85
- package/lib/task/artifact-operations.ts +59 -28
- package/lib/task/artifact-receipts.ts +4 -1
- package/lib/task/artifact-schema.ts +10 -7
- package/lib/task/artifact-selection.ts +53 -0
- package/lib/task/capabilities.ts +154 -40
- package/lib/task/commands/status.ts +11 -2
- package/lib/task/control-authority.ts +17 -189
- package/lib/task/decision-intents.ts +11 -4
- package/lib/task/delivery.ts +1 -40
- package/lib/task/events.ts +73 -74
- package/lib/task/finalization-handoff.ts +104 -0
- package/lib/task/finalization.ts +388 -122
- package/lib/task/intermediate-cleanup.ts +9 -125
- package/lib/task/ledger-intents.ts +157 -20
- package/lib/task/lifecycle-path.ts +98 -0
- package/lib/task/lifecycle.ts +58 -13
- package/lib/task/local-artifact-finalization.ts +14 -56
- package/lib/task/orchestration.ts +26 -8
- package/lib/task/review-command.ts +2 -5
- package/lib/task/review-finalization.ts +4 -20
- package/lib/task/rework-intent.ts +75 -5
- package/lib/task/snapshot.ts +6 -6
- package/lib/task/verification-engine.ts +29 -30
- package/lib/task/verification.ts +3 -16
- package/lib/task/workflow-warning-intents.ts +20 -10
- package/lib/task/workspace-snapshot.ts +3 -2
- package/lib/task/write.ts +1 -4
- package/package.json +1 -1
- package/templates/.agents/rules/review-handshake.en.md +4 -4
- package/templates/.agents/rules/review-handshake.zh-CN.md +4 -4
- package/templates/.agents/skills/analyze-task/SKILL.en.md +21 -5
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +21 -5
- package/templates/.agents/skills/code-task/SKILL.en.md +14 -8
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +18 -13
- package/templates/.agents/skills/code-task/reference/code-rules.en.md +2 -2
- package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +4 -4
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +4 -4
- package/templates/.agents/skills/code-task/reference/report-template.en.md +7 -7
- package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +7 -7
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +2 -2
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +2 -2
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +1 -3
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +1 -3
- package/templates/.agents/skills/complete-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-task/config/verify.en.json +2 -2
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +2 -2
- package/templates/.agents/skills/plan-task/SKILL.en.md +13 -10
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +13 -10
- package/templates/.agents/skills/review-analysis/SKILL.en.md +5 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +3 -3
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/review-code/SKILL.en.md +5 -1
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/review-code/reference/report-template.en.md +3 -3
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/review-plan/SKILL.en.md +5 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +3 -3
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/review-pr/config/verify.en.json +3 -1
- package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +3 -1
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +3 -3
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/run-manual-validation/config/verify.en.json +2 -2
- package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +2 -2
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -2
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +18 -2
- package/templates/.agents/templates/task.en.md +2 -2
- package/templates/.agents/templates/task.zh-CN.md +2 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +11 -6
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +11 -6
- package/templates/.agents/workflows/feature-development.en.yaml +11 -6
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +11 -6
- package/templates/.agents/workflows/refactoring.en.yaml +11 -6
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +11 -6
- package/dist/lib/internal/task-override.js +0 -138
- package/dist/lib/sandbox/control/finalization-response.js +0 -33
- package/dist/lib/task/artifact-recovery.js +0 -476
- package/dist/lib/task/artifact-repair-intent.js +0 -181
- package/dist/lib/task/guard-override.js +0 -31
- package/dist/lib/task/human-override.js +0 -1259
- package/lib/internal/task-override.ts +0 -144
- package/lib/sandbox/control/finalization-response.ts +0 -35
- package/lib/task/artifact-recovery.ts +0 -572
- package/lib/task/artifact-repair-intent.ts +0 -227
- package/lib/task/guard-override.ts +0 -50
- package/lib/task/human-override.ts +0 -1522
|
@@ -23,6 +23,7 @@ import { inspectPlatformPullRequest } from "../platform/pull-requests.ts";
|
|
|
23
23
|
import { resolveMaterializedReviewedHeadRelation } from "../platform/change-request-git-evidence.ts";
|
|
24
24
|
import { resolveReviewedHeadRelation } from "../platform/merged-pr-equivalence.ts";
|
|
25
25
|
import { resolveLocalReviewedCommitRelation } from "../git/reviewed-commit-equivalence.ts";
|
|
26
|
+
import { resolveBranchWorktree } from "../git/branch-worktree.ts";
|
|
26
27
|
import { parseTypedTaskFrontmatter } from "./frontmatter.ts";
|
|
27
28
|
import { LEDGER_TERMINAL, LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from "./ledger.ts";
|
|
28
29
|
import type { LedgerRow } from "./ledger.ts";
|
|
@@ -40,7 +41,6 @@ import type { OrchestrationRun } from "./orchestration.ts";
|
|
|
40
41
|
import { resolveDeliveryTarget } from "./delivery-target.ts";
|
|
41
42
|
import { readPrDeliveryFact } from "./pr-delivery-fact.ts";
|
|
42
43
|
import { validateLocalArtifact } from "./local-artifact-finalization.ts";
|
|
43
|
-
import { validateQualificationAudit } from "./qualification-audit.ts";
|
|
44
44
|
import { getArtifactSchema } from "./artifact-schema.ts";
|
|
45
45
|
import { inspectArtifactContract } from "./artifact-operations.ts";
|
|
46
46
|
import type { VerificationShared } from "./verification-types.ts";
|
|
@@ -78,7 +78,6 @@ const BRANCH_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
|
78
78
|
|
|
79
79
|
// Review disagreement ledger (see .agents/rules/review-handshake.md).
|
|
80
80
|
const LEDGER_SECTION_NAMES = ["审查分歧账本", "Review Disagreement Ledger"];
|
|
81
|
-
const DEFAULT_MAX_HANDSHAKE_ROUNDS = 3;
|
|
82
81
|
const POST_REVIEW_COMMIT_STAGE = "post-review-commit";
|
|
83
82
|
const SHA_PATTERN = /^[0-9a-f]{7,40}$/i;
|
|
84
83
|
|
|
@@ -511,19 +510,6 @@ function checkArtifact({ taskDir, config, artifactFile, skillName }: any): any {
|
|
|
511
510
|
}
|
|
512
511
|
|
|
513
512
|
const content = fs.readFileSync(artifactPath, "utf8");
|
|
514
|
-
let taskContent = "";
|
|
515
|
-
const taskPath = path.join(taskDir, "task.md");
|
|
516
|
-
if (fs.existsSync(taskPath)) {
|
|
517
|
-
try {
|
|
518
|
-
taskContent = fs.readFileSync(taskPath, "utf8");
|
|
519
|
-
} catch (error) {
|
|
520
|
-
return failResult("artifact", `Cannot read task qualification contract: ${error instanceof Error ? error.message : String(error)}`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
if (taskContent && /^review-(?:analysis|plan|code)$/.test(skillName)) {
|
|
524
|
-
const qualification = validateQualificationAudit(taskContent, content, { artifact: path.basename(artifactPath) });
|
|
525
|
-
if (!qualification.ok) return failResult("artifact", `${path.basename(artifactPath)} has qualification audit errors: ${qualification.code}: ${qualification.message}`);
|
|
526
|
-
}
|
|
527
513
|
const schemaFamily = skillName === "analyze-task"
|
|
528
514
|
? "analysis"
|
|
529
515
|
: skillName === "review-analysis"
|
|
@@ -547,9 +533,7 @@ function checkArtifact({ taskDir, config, artifactFile, skillName }: any): any {
|
|
|
547
533
|
}
|
|
548
534
|
if (localFamily) {
|
|
549
535
|
const local = validateLocalArtifact(content, {
|
|
550
|
-
family: localFamily
|
|
551
|
-
...(taskContent ? { taskContent } : {}),
|
|
552
|
-
artifact: path.basename(artifactPath)
|
|
536
|
+
family: localFamily
|
|
553
537
|
});
|
|
554
538
|
if (!local.ok) {
|
|
555
539
|
return failResult(
|
|
@@ -587,6 +571,23 @@ function checkArtifact({ taskDir, config, artifactFile, skillName }: any): any {
|
|
|
587
571
|
}
|
|
588
572
|
}
|
|
589
573
|
|
|
574
|
+
const stateCheckPatterns = config.state_check_patterns || [];
|
|
575
|
+
if (stateCheckPatterns.length > 0) {
|
|
576
|
+
const scanned = scanVisibleMarkdown(content);
|
|
577
|
+
const stateCheckHeading = scanned.headings.find((heading) => (
|
|
578
|
+
heading.level === 2 && (heading.text === "状态核对" || heading.text === "State Check")
|
|
579
|
+
));
|
|
580
|
+
const nextHeading = stateCheckHeading && scanned.headings.find((heading) => (
|
|
581
|
+
heading.start > stateCheckHeading.start && heading.level <= 2
|
|
582
|
+
));
|
|
583
|
+
const stateCheckBody = stateCheckHeading ? content.slice(stateCheckHeading.end, nextHeading?.start ?? content.length) : "";
|
|
584
|
+
for (const pattern of stateCheckPatterns) {
|
|
585
|
+
if (!new RegExp(pattern, "m").test(stateCheckBody)) {
|
|
586
|
+
return failResult("artifact", `${path.basename(artifactPath)} state-check section is missing required command: ${pattern}`);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
590
591
|
return passResult(
|
|
591
592
|
"artifact",
|
|
592
593
|
`${path.basename(artifactPath)} passed (${requiredSections.length} sections)`
|
|
@@ -818,12 +819,11 @@ function checkReviewLedger({ taskDir, config, repositoryRoot }: any): any {
|
|
|
818
819
|
}
|
|
819
820
|
|
|
820
821
|
const stageScope = Array.isArray(config.stage_scope) ? config.stage_scope : null;
|
|
821
|
-
const maxRounds = Number(resolveReviewSetting(config, "maxHandshakeRounds", DEFAULT_MAX_HANDSHAKE_ROUNDS, repositoryRoot));
|
|
822
822
|
const problems = [];
|
|
823
823
|
let inScopeCount = 0;
|
|
824
824
|
|
|
825
825
|
for (const row of rows) {
|
|
826
|
-
const { id, stage,
|
|
826
|
+
const { id, stage, status, evidence } = row;
|
|
827
827
|
const stageScoped = stageScope ? stageScope.includes(stage) : true;
|
|
828
828
|
// post-review-commit exemption rows are consumed by the post-review-commit
|
|
829
829
|
// check, not enforced here.
|
|
@@ -843,15 +843,6 @@ function checkReviewLedger({ taskDir, config, repositoryRoot }: any): any {
|
|
|
843
843
|
if (status !== "open" && evidence === "") {
|
|
844
844
|
problems.push(`${id}: status '${status}' requires evidence`);
|
|
845
845
|
}
|
|
846
|
-
const round = Number.parseInt(roundRaw!, 10);
|
|
847
|
-
if (
|
|
848
|
-
Number.isFinite(round) &&
|
|
849
|
-
round >= maxRounds &&
|
|
850
|
-
!LEDGER_TERMINAL.has(status!) &&
|
|
851
|
-
status !== "needs-human-decision"
|
|
852
|
-
) {
|
|
853
|
-
problems.push(`${id}: round ${round} reached limit ${maxRounds} without convergence; escalate to needs-human-decision`);
|
|
854
|
-
}
|
|
855
846
|
if (!LEDGER_TERMINAL.has(status!)) {
|
|
856
847
|
problems.push(`${id}: unresolved (status '${status}')`);
|
|
857
848
|
}
|
|
@@ -1194,7 +1185,8 @@ function checkReviewFact({ taskDir, artifactFile, repositoryRoot }: any): any {
|
|
|
1194
1185
|
let targetHead;
|
|
1195
1186
|
let diffBase;
|
|
1196
1187
|
try {
|
|
1197
|
-
|
|
1188
|
+
const taskRepositoryRoot = execFileSync("git", ["-C", taskDir, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
|
|
1189
|
+
gitRoot = reviewWorktreeForTask(taskRepositoryRoot, String(task.metadata.branch || "").trim()) ?? taskRepositoryRoot;
|
|
1198
1190
|
head = execFileSync("git", ["-C", gitRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
1199
1191
|
const target = resolveDeliveryTarget(gitRoot, { remote: deliveryRemote, baseRef: deliveryBaseRef });
|
|
1200
1192
|
if (!target.ok) throw new Error(target.message);
|
|
@@ -1275,6 +1267,13 @@ function checkReviewFact({ taskDir, artifactFile, repositoryRoot }: any): any {
|
|
|
1275
1267
|
);
|
|
1276
1268
|
}
|
|
1277
1269
|
|
|
1270
|
+
function reviewWorktreeForTask(repositoryRoot: string, branch: string): string | null {
|
|
1271
|
+
if (!branch) return null;
|
|
1272
|
+
const worktree = resolveBranchWorktree(repositoryRoot, branch);
|
|
1273
|
+
if (worktree) return worktree;
|
|
1274
|
+
throw new Error(`Task branch '${branch}' is not checked out in a registered worktree`);
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1278
1277
|
function resolvePostReviewBaseline({ gitRoot, lastReviewedCommit, reviewArtifact }: any): any {
|
|
1279
1278
|
if (SHA_PATTERN.test(lastReviewedCommit) && gitCommitExists(gitRoot, lastReviewedCommit)) {
|
|
1280
1279
|
return { ok: true, sha: lastReviewedCommit };
|
package/lib/task/verification.ts
CHANGED
|
@@ -7,15 +7,13 @@ import { parseArtifactName } from './artifact-name.ts';
|
|
|
7
7
|
import type { ArtifactFamily } from './artifact-lifecycle.ts';
|
|
8
8
|
import { resolveTaskRef } from './resolve-ref.ts';
|
|
9
9
|
import type { TaskWorkspaceState } from './resolve-ref.ts';
|
|
10
|
-
import { allowsManualOverride } from './guard-override.ts';
|
|
11
|
-
import type { ManualOverrideCapability } from './guard-override.ts';
|
|
12
10
|
|
|
13
11
|
type VerificationEvent =
|
|
14
12
|
| 'analyze.awaiting-input' | 'analyze.completed'
|
|
15
13
|
| 'review-analysis.completed' | 'plan.completed' | 'review-plan.completed'
|
|
16
14
|
| 'code.completed' | 'review-code.completed' | 'manual-validation.completed' | 'validation-run.completed'
|
|
17
15
|
| 'block-task.completed' | 'cancel-task.completed' | 'commit.completed'
|
|
18
|
-
| 'complete-task.preflight' | 'complete-task.hard-preflight' | 'complete-task.completed'
|
|
16
|
+
| 'complete-task.preflight' | 'complete-task.hard-preflight' | 'complete-task.prepared' | 'complete-task.completed'
|
|
19
17
|
| 'create-pr.completed' | 'create-task.completed'
|
|
20
18
|
| 'import-codescan.completed' | 'import-dependabot.completed'
|
|
21
19
|
| 'import-issue.completed' | 'watch-pr.completed'
|
|
@@ -50,7 +48,6 @@ type TaskVerificationResult = {
|
|
|
50
48
|
type VerificationOptions = {
|
|
51
49
|
repoRoot?: string;
|
|
52
50
|
engine?: (input: Parameters<typeof verifyInProcess>[0]) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
53
|
-
manualOverride?: ManualOverrideCapability;
|
|
54
51
|
};
|
|
55
52
|
|
|
56
53
|
const gate = (skill: string, expectedState: VerificationSpec['expectedState'], artifactFamily?: ArtifactFamily): VerificationSpec => ({
|
|
@@ -71,6 +68,7 @@ const VERIFICATION_CATALOG: Readonly<Record<VerificationEvent, VerificationSpec>
|
|
|
71
68
|
'commit.completed': gate('commit', 'active'),
|
|
72
69
|
'complete-task.preflight': { skill: 'complete-task', expectedState: 'active', mode: 'checks', checks: ['required-pr-delivery'] },
|
|
73
70
|
'complete-task.hard-preflight': { skill: 'complete-task', expectedState: 'active', mode: 'checks', checks: ['required-pr-delivery'] },
|
|
71
|
+
'complete-task.prepared': gate('complete-task', 'active'),
|
|
74
72
|
'complete-task.completed': gate('complete-task', 'completed'),
|
|
75
73
|
'create-pr.completed': gate('create-pr', 'active'),
|
|
76
74
|
'create-task.completed': gate('create-task', 'active'),
|
|
@@ -97,7 +95,7 @@ async function verifyTaskEvent(request: { taskRef: string; event: string; artifa
|
|
|
97
95
|
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
98
96
|
if (!resolved.ok) return failure(request, resolved.code, resolved.message, { taskId: resolved.taskId, skill: spec.skill, mode: spec.mode });
|
|
99
97
|
const identity = { taskId: resolved.taskId, taskDir: resolved.taskDir, taskState: resolved.state, skill: spec.skill, mode: spec.mode } as const;
|
|
100
|
-
if (resolved.state !== spec.expectedState
|
|
98
|
+
if (resolved.state !== spec.expectedState) {
|
|
101
99
|
return failure(request, 'VERIFY_TASK_STATE_MISMATCH', `event '${request.event}' requires workspace '${spec.expectedState}', received '${resolved.state}'`, identity);
|
|
102
100
|
}
|
|
103
101
|
if (spec.artifactFamily) {
|
|
@@ -115,22 +113,11 @@ async function verifyTaskEvent(request: { taskRef: string; event: string; artifa
|
|
|
115
113
|
if (spec.mode === 'gate') {
|
|
116
114
|
const payload = await engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot });
|
|
117
115
|
const status = payload.gate as 'pass' | 'fail' | 'blocked';
|
|
118
|
-
if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
|
|
119
|
-
invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, gate: 'pass', humanOverride: 'human-approved', originalGate: status } });
|
|
120
|
-
return {
|
|
121
|
-
status: 'pass', changed: false, event: request.event, requestRef: request.taskRef,
|
|
122
|
-
...identity, artifact: request.artifact ?? null, invocations, error: null
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
116
|
invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
|
|
126
117
|
} else {
|
|
127
118
|
for (const check of spec.checks ?? []) {
|
|
128
119
|
const payload = await engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot });
|
|
129
120
|
const status = (payload.effectiveStatus ?? payload.status) as 'pass' | 'fail' | 'blocked';
|
|
130
|
-
if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
|
|
131
|
-
invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, status: 'pass', humanOverride: 'human-approved', originalStatus: status } });
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
121
|
invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
|
|
135
122
|
if (status !== 'pass') break;
|
|
136
123
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
|
|
3
3
|
import { resolveTaskRef } from './resolve-ref.ts';
|
|
4
|
+
import { parseTaskFrontmatter } from './frontmatter.ts';
|
|
4
5
|
import {
|
|
5
6
|
WORKFLOW_WARNING_COLUMNS,
|
|
6
7
|
WORKFLOW_WARNING_HEADINGS,
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
import type { WorkflowWarning } from './workflow-warnings.ts';
|
|
12
13
|
import { captureTaskWriteMetadata, writeTask } from './write.ts';
|
|
13
14
|
import type { TaskMutation, TaskOperationSummary, TaskWriteOptions } from './write.ts';
|
|
14
|
-
import { allowsManualOverride } from './guard-override.ts';
|
|
15
15
|
import { retryHintForWarning, type OperationWarning } from './operation-outcome.ts';
|
|
16
16
|
|
|
17
17
|
type WarningSeverity = 'IMPORTANT' | 'ACTION_REQUIRED';
|
|
@@ -76,8 +76,7 @@ function rowMutation(row: WorkflowWarning): TaskMutation {
|
|
|
76
76
|
function applyWorkflowWarningIntent(intent: WorkflowWarningIntent, options: TaskWriteOptions = {}): WorkflowWarningIntentResult {
|
|
77
77
|
const resolved = resolveTaskRef(intent.taskRef, { repoRoot: options.repoRoot });
|
|
78
78
|
if (!resolved.ok) return failed(intent, resolved.code, resolved.message, resolved.taskId);
|
|
79
|
-
|
|
80
|
-
if (resolved.state !== 'active' && !stateOverride) return failed(intent, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected active`, resolved.taskId);
|
|
79
|
+
if (resolved.state !== 'active') return failed(intent, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected active`, resolved.taskId);
|
|
81
80
|
let content: string;
|
|
82
81
|
let rows: WorkflowWarning[];
|
|
83
82
|
try {
|
|
@@ -121,7 +120,7 @@ function applyWorkflowWarningIntent(intent: WorkflowWarningIntent, options: Task
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
const writeResult = writeTask({
|
|
124
|
-
taskRef: intent.taskRef, expectedState:
|
|
123
|
+
taskRef: intent.taskRef, expectedState: 'active', mutations: [...sectionMutation(content), rowMutation(after)], dryRun: intent.dryRun
|
|
125
124
|
}, {
|
|
126
125
|
...options,
|
|
127
126
|
taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state: resolved.state },
|
|
@@ -137,11 +136,18 @@ function applyWorkflowWarningIntent(intent: WorkflowWarningIntent, options: Task
|
|
|
137
136
|
function projectFinalizationWarning(
|
|
138
137
|
taskRef: string,
|
|
139
138
|
warning: OperationWarning & { status: 'open' | 'resolved'; resolvedAt: string | null },
|
|
140
|
-
options: TaskWriteOptions = {}
|
|
139
|
+
options: TaskWriteOptions & { resolution?: 'passed' | 'superseded' } = {}
|
|
141
140
|
): FinalizationWarningProjectionResult {
|
|
142
141
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
143
142
|
if (!resolved.ok) return { status: 'failed', changed: false, error: { code: resolved.code, message: resolved.message } };
|
|
144
|
-
|
|
143
|
+
let prepared = resolved.state === 'completed';
|
|
144
|
+
if (!prepared && resolved.state === 'active') {
|
|
145
|
+
try { prepared = parseTaskFrontmatter(fs.readFileSync(resolved.taskMdPath, 'utf8')).status === 'completed'; }
|
|
146
|
+
catch { prepared = false; }
|
|
147
|
+
}
|
|
148
|
+
if (!prepared) {
|
|
149
|
+
return { status: 'failed', changed: false, error: { code: 'TASK_STATE_MISMATCH', message: `task ${resolved.taskId} is ${resolved.state}, expected a prepared or completed task` } };
|
|
150
|
+
}
|
|
145
151
|
let content: string;
|
|
146
152
|
let rows: WorkflowWarning[];
|
|
147
153
|
try {
|
|
@@ -160,22 +166,26 @@ function projectFinalizationWarning(
|
|
|
160
166
|
message: warning.message,
|
|
161
167
|
action: retryHintForWarning(warning),
|
|
162
168
|
resolvedAt: warning.resolvedAt || (warning.status === 'resolved' ? metadata.timestamp : ''),
|
|
163
|
-
resolution: warning.status === 'resolved'
|
|
169
|
+
resolution: warning.status === 'resolved'
|
|
170
|
+
? options.resolution === 'superseded' ? 'Superseded by a later verification observation' : 'Resolved by a successful finalization retry'
|
|
171
|
+
: ''
|
|
164
172
|
}
|
|
165
173
|
: {
|
|
166
174
|
id: nextWarningId(rows), time: metadata.timestamp, step: warning.step,
|
|
167
175
|
severity: warning.severity, code: warning.code, status: warning.status,
|
|
168
176
|
target: warning.target, message: warning.message, action: retryHintForWarning(warning),
|
|
169
|
-
resolvedAt: warning.resolvedAt || '', resolution: warning.status === 'resolved'
|
|
177
|
+
resolvedAt: warning.resolvedAt || '', resolution: warning.status === 'resolved'
|
|
178
|
+
? options.resolution === 'superseded' ? 'Superseded by a later verification observation' : 'Resolved by a successful finalization retry'
|
|
179
|
+
: ''
|
|
170
180
|
};
|
|
171
181
|
if (existing && JSON.stringify(existing) === JSON.stringify(after)) return { status: 'no-op', changed: false, error: null };
|
|
172
182
|
const written = writeTask({
|
|
173
183
|
taskRef: resolved.taskId,
|
|
174
|
-
expectedState:
|
|
184
|
+
expectedState: resolved.state,
|
|
175
185
|
mutations: [...sectionMutation(content), rowMutation(after)]
|
|
176
186
|
}, {
|
|
177
187
|
...options,
|
|
178
|
-
taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state:
|
|
188
|
+
taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state: resolved.state },
|
|
179
189
|
metadataProvider: () => metadata
|
|
180
190
|
});
|
|
181
191
|
if (written.status === 'failed') return { status: 'failed', changed: false, error: { code: written.error.code, message: written.error.message } };
|
|
@@ -42,7 +42,8 @@ function captureWorktreeTree(repoRoot: string, forcedPath: string | null): strin
|
|
|
42
42
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-infra-orchestration-index-'));
|
|
43
43
|
const indexFile = path.join(tempDir, 'index');
|
|
44
44
|
try {
|
|
45
|
-
git(repoRoot, indexFile, ['read-tree', 'HEAD']);
|
|
45
|
+
try { git(repoRoot, indexFile, ['read-tree', 'HEAD']); }
|
|
46
|
+
catch { git(repoRoot, indexFile, ['read-tree', '--empty']); }
|
|
46
47
|
git(repoRoot, indexFile, ['add', '-A', '--', ':/']);
|
|
47
48
|
if (forcedPath && fs.existsSync(path.join(repoRoot, forcedPath))) {
|
|
48
49
|
git(repoRoot, indexFile, ['add', '-f', '--', forcedPath]);
|
|
@@ -138,5 +139,5 @@ function diffWorkspaceSnapshots(repoRoot: string, before: string, after: string)
|
|
|
138
139
|
return [...changed].sort();
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
export { captureRepositorySnapshot, captureWorkspaceSnapshot, diffWorkspaceSnapshots };
|
|
142
|
+
export { captureRepositorySnapshot, captureWorkspaceSnapshot, captureWorktreeTree, diffWorkspaceSnapshots };
|
|
142
143
|
export type { OrchestrationWorkspaceFingerprint, RepositorySnapshot, WorkspaceSnapshotContext };
|
package/lib/task/write.ts
CHANGED
|
@@ -12,8 +12,6 @@ import type {
|
|
|
12
12
|
ResolveTaskRefErrorCode,
|
|
13
13
|
TaskWorkspaceState
|
|
14
14
|
} from './resolve-ref.ts';
|
|
15
|
-
import { allowsManualOverride } from './guard-override.ts';
|
|
16
|
-
import type { ManualOverrideCapability } from './guard-override.ts';
|
|
17
15
|
import { mutateTableRow, upsertSection } from './sections.ts';
|
|
18
16
|
import { validateCurrentTaskContract } from './current-contract.ts';
|
|
19
17
|
import { invalidationBlocks, parseInvalidationDocument } from './invalidation.ts';
|
|
@@ -163,7 +161,6 @@ type TaskWriteOptions = {
|
|
|
163
161
|
metadataProvider?: () => TaskWriteMetadata;
|
|
164
162
|
randomSuffix?: () => string;
|
|
165
163
|
fileSystem?: Partial<TaskFileSystem>;
|
|
166
|
-
manualOverride?: ManualOverrideCapability;
|
|
167
164
|
invalidationContext?: 'standard' | 'source-completion' | 'reconcile';
|
|
168
165
|
};
|
|
169
166
|
|
|
@@ -250,7 +247,7 @@ function writeTask(request: TaskWriteRequest, options: TaskWriteOptions = {}): T
|
|
|
250
247
|
taskMdPath: resolved.taskMdPath,
|
|
251
248
|
actualState: resolved.state
|
|
252
249
|
};
|
|
253
|
-
if (resolved.state !== request.expectedState
|
|
250
|
+
if (resolved.state !== request.expectedState) {
|
|
254
251
|
return failure(
|
|
255
252
|
request,
|
|
256
253
|
identity,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fitlab-ai/agent-infra",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
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",
|
|
@@ -29,11 +29,11 @@ After the executor gives `adjusted` / `refuted` / `cannot-judge`, the reviewer m
|
|
|
29
29
|
- **Hold with new evidence** → set back to `open` (with new evidence, returned to the executor).
|
|
30
30
|
- **Escalate to human** → set to `needs-human-decision`.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Evidence-driven rework convergence
|
|
33
33
|
|
|
34
|
-
- The
|
|
35
|
-
-
|
|
36
|
-
-
|
|
34
|
+
- The first Changes Requested verdict permits an ordinary revision. After one revision-review cycle, another Changes Requested verdict must classify the problem as scope or requirements, design, implementation, human decision, or insufficient evidence before another executor artifact is created.
|
|
35
|
+
- Classification binds the finding, source review SHA, and stable task-fact digest. Artifact names, rounds, and retry counts are not evidence by themselves.
|
|
36
|
+
- Human choice and insufficient evidence pause stably; implementation can continue when new decisive evidence exists. Retry count alone never forces a human escalation.
|
|
37
37
|
|
|
38
38
|
## Same-model convergence-bias mitigation (documentation-level discipline)
|
|
39
39
|
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
- **补充新证据后坚持** → 账本置回 `open`(带新证据,回到执行方)。
|
|
30
30
|
- **升级人工裁决** → 账本置 `needs-human-decision`。
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## 证据驱动的返工收敛
|
|
33
33
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
34
|
+
- 首次 Changes Requested 允许正常修订。完成一次修订—复审后再次收到 Changes Requested 时,必须在下一执行产物前把问题分类为范围或需求、方案、实现、人工裁决或证据不足。
|
|
35
|
+
- 分类必须绑定 finding、来源审查 SHA 和稳定任务事实摘要。文件名、artifact round 或返工次数本身不构成新证据。
|
|
36
|
+
- 人工选择或证据不足进入稳定暂停;具有新决定性证据的实现缺陷可以继续修订。不得仅因次数达到阈值强制升级人工裁决。
|
|
37
37
|
|
|
38
38
|
## 同源模型收敛偏差缓解(文档级纪律)
|
|
39
39
|
|
|
@@ -13,6 +13,10 @@ If the entry operands contain `--orchestrated`, bind `{execution-flag}` to `--or
|
|
|
13
13
|
|
|
14
14
|
## Boundary / Critical Rules
|
|
15
15
|
|
|
16
|
+
### Flow decision
|
|
17
|
+
|
|
18
|
+
The analysis artifact must record `Path`, `Basis`, `Unmet Higher-path Conditions`, and `Upgrade Triggers` exactly once each, with non-empty values, in `## Flow Decision`. The path is streamlined, standard, or full; file count, module count, and speculative risk cannot upgrade it by themselves. The analysis `finalize-local` reuses the lifecycle-path parser to validate this decision; directly repair the formal artifact and rerun it for missing, duplicate, or invalid values.
|
|
19
|
+
|
|
16
20
|
### Persisted Report Evidence
|
|
17
21
|
|
|
18
22
|
Before generating the analysis report, read `.agents/rules/evidence-reporting.md`. Record the command, target scope, status or structured result, actual result, and uncovered parts for state checks and successful checks; include decisive raw excerpts only for failures, blocking conditions, or disputes.
|
|
@@ -61,7 +65,7 @@ If `task.md` is missing, tell the user to create or import the task first.
|
|
|
61
65
|
|
|
62
66
|
### 2. Resolve the Analysis Context
|
|
63
67
|
|
|
64
|
-
Run `agent-infra-internal task-artifact {task-id} inspect --family analysis`. Continue only for `ready
|
|
68
|
+
Run `agent-infra-internal task-artifact {task-id} inspect --family analysis`. Continue only for `ready`. When `selection.disposition` is `reuse`, reuse `selection.artifact`, do not run started/init or write a new artifact, and continue directly to completion verification and next-step guidance. Otherwise take `{analysis-round}` / `{analysis-artifact}` from `next.round` / `next.name` and revision inputs from `inputs`. Do not scan rounds or construct names in the skill.
|
|
65
69
|
|
|
66
70
|
### 3. Read Task Context
|
|
67
71
|
|
|
@@ -156,7 +160,7 @@ Create `.agents/workspace/active/{task-id}/{analysis-artifact}`.
|
|
|
156
160
|
|
|
157
161
|
## State Check
|
|
158
162
|
|
|
159
|
-
> Record the Step 0 state-check command, task/artifact scope, key result, and uncovered parts
|
|
163
|
+
> Record the Step 0 state-check command, task/artifact scope, key result, and uncovered parts. Do not paste complete directory listings or task tails on normal success; retain decisive raw lines only for failures, blocking conditions, identity mismatches, or disputes.
|
|
160
164
|
|
|
161
165
|
## Requirement Source
|
|
162
166
|
|
|
@@ -183,6 +187,15 @@ Create `.agents/workspace/active/{task-id}/{analysis-artifact}`.
|
|
|
183
187
|
## Dependencies
|
|
184
188
|
- {Required dependencies and coordination with other modules}
|
|
185
189
|
|
|
190
|
+
<!-- lifecycle-path-decision-template:start -->
|
|
191
|
+
## Flow Decision
|
|
192
|
+
|
|
193
|
+
- **Path**: {lifecycle-path}
|
|
194
|
+
- **Basis**: {Factual basis for selecting the current path}
|
|
195
|
+
- **Unmet Higher-path Conditions**: {Factual conditions for the higher path that are not met; for full, state that no higher path exists}
|
|
196
|
+
- **Upgrade Triggers**: {Factual triggers that require reassessing the path}
|
|
197
|
+
<!-- lifecycle-path-decision-template:end -->
|
|
198
|
+
|
|
186
199
|
## Assumptions
|
|
187
200
|
|
|
188
201
|
> If this analysis depends on assumptions, list them here; omit this section if there are none.
|
|
@@ -261,7 +274,10 @@ Keep the gate output in your reply as fresh evidence. Do not claim completion wi
|
|
|
261
274
|
> Before rendering next steps, read `.agents/rules/next-step-output.md`, invoke the shared helper only for the selected scenario, and insert its stdout at `{next-step-commands}`.
|
|
262
275
|
|
|
263
276
|
Output format:
|
|
264
|
-
|
|
277
|
+
Select one command from the canonical path to populate `{next-step-commands}`:
|
|
278
|
+
- Streamlined: `agent-infra-internal agent-client next-steps --skill code-task --task-ref {task-ref}`
|
|
279
|
+
- Standard: `agent-infra-internal agent-client next-steps --skill plan-task --task-ref {task-ref}`
|
|
280
|
+
- Full: `agent-infra-internal agent-client next-steps --skill review-analysis --task-ref {task-ref}`
|
|
265
281
|
|
|
266
282
|
```
|
|
267
283
|
Analysis complete for task {task-id}.
|
|
@@ -274,7 +290,7 @@ Summary:
|
|
|
274
290
|
Output file:
|
|
275
291
|
- Analysis report: .agents/workspace/active/{task-id}/{analysis-artifact}
|
|
276
292
|
|
|
277
|
-
Next step -
|
|
293
|
+
Next step - continue on the selected path:
|
|
278
294
|
{next-step-commands}
|
|
279
295
|
```
|
|
280
296
|
|
|
@@ -292,7 +308,7 @@ Next step - review the analysis:
|
|
|
292
308
|
|
|
293
309
|
## STOP
|
|
294
310
|
|
|
295
|
-
After completing the checklist, **stop immediately**. Wait for the user to
|
|
311
|
+
After completing the checklist, **stop immediately**. Wait for the user to invoke the next stage selected above.
|
|
296
312
|
|
|
297
313
|
## Notes
|
|
298
314
|
|
|
@@ -13,6 +13,10 @@ description: >
|
|
|
13
13
|
|
|
14
14
|
## 行为边界 / 关键规则
|
|
15
15
|
|
|
16
|
+
### 流程裁定
|
|
17
|
+
|
|
18
|
+
分析产物必须在 `## 流程裁定` 中记录 `本任务路径`、`判定依据`、`未满足的更高路径条件` 和 `升级触发条件` 四个字段,每个字段恰好一次且非空。路径仅可为精简、标准或完整;文件数、模块数和推测性风险不能单独升级路径。analysis 的 `finalize-local` 会复用生命周期路径解析器校验该决定;缺失、重复或无效值必须直接修复正式产物后重跑。
|
|
19
|
+
|
|
16
20
|
### 持久化报告证据
|
|
17
21
|
|
|
18
22
|
生成分析报告时,先读取 `.agents/rules/evidence-reporting.md`。状态核对和成功检查记录命令、目标范围、状态/结构化结果、实际结果和未覆盖部分;失败、阻塞或争议才附决定性原文摘录。
|
|
@@ -64,7 +68,7 @@ agent-infra-internal task-event {task-id} analyze.started --agent {standard-agen
|
|
|
64
68
|
|
|
65
69
|
### 2. 解析分析上下文
|
|
66
70
|
|
|
67
|
-
运行 `agent-infra-internal task-artifact {task-id} inspect --family analysis`。仅当结果为 `ready`
|
|
71
|
+
运行 `agent-infra-internal task-artifact {task-id} inspect --family analysis`。仅当结果为 `ready` 时继续。若 `selection.disposition` 为 `reuse`,复用 `selection.artifact`,不得执行 started、init 或写入新产物,并直接进入完成校验与下一步提示。其他状态从 `next.round` / `next.name` 记录 `{analysis-round}` / `{analysis-artifact}`,从 `inputs` 读取修订上下文;不得自行扫描轮次或拼装文件名。随后执行 started 事件,并以事件返回的 `artifactContext` 复核同一身份。
|
|
68
72
|
|
|
69
73
|
### 3. 阅读任务上下文
|
|
70
74
|
|
|
@@ -159,7 +163,7 @@ agent-infra-internal task-artifact {task-id} init --family analysis --artifact {
|
|
|
159
163
|
|
|
160
164
|
## 状态核对
|
|
161
165
|
|
|
162
|
-
> 记录第 0
|
|
166
|
+
> 记录第 0 步状态核对命令、任务/产物范围、关键结果和未覆盖部分。正常成功不粘贴完整目录清单或 `task.md` 尾部,失败、阻塞、身份不一致或争议时附决定性原文行。
|
|
163
167
|
|
|
164
168
|
## 需求来源
|
|
165
169
|
|
|
@@ -186,6 +190,15 @@ agent-infra-internal task-artifact {task-id} init --family analysis --artifact {
|
|
|
186
190
|
## 依赖关系
|
|
187
191
|
- {需要的依赖和与其他模块的协调}
|
|
188
192
|
|
|
193
|
+
<!-- lifecycle-path-decision-template:start -->
|
|
194
|
+
## 流程裁定
|
|
195
|
+
|
|
196
|
+
- **本任务路径**:{lifecycle-path}
|
|
197
|
+
- **判定依据**:{选择当前路径的事实依据}
|
|
198
|
+
- **未满足的更高路径条件**:{当前未满足的更高路径条件;完整路径写不存在更高路径的事实}
|
|
199
|
+
- **升级触发条件**:{未来需要重新评估路径的事实触发条件}
|
|
200
|
+
<!-- lifecycle-path-decision-template:end -->
|
|
201
|
+
|
|
189
202
|
## 资格审计
|
|
190
203
|
|
|
191
204
|
> 按 `.agents/rules/decision-qualification.md` 填写约束依赖、候选资格、分类结果、上游关系、依赖快照五张表;没有 artifact 上游时保留空表头,不虚构关系。
|
|
@@ -261,7 +274,10 @@ agent-infra-internal task-verify {task-id} analyze.completed --artifact {analysi
|
|
|
261
274
|
> 渲染下一步前先读取 `.agents/rules/next-step-output.md`,仅为已选场景调用统一 helper,并将 stdout 填入 `{next-step-commands}`。
|
|
262
275
|
|
|
263
276
|
输出格式:
|
|
264
|
-
|
|
277
|
+
按分析中的规范路径选择一条命令生成 `{next-step-commands}`:
|
|
278
|
+
- 精简路径:`agent-infra-internal agent-client next-steps --skill code-task --task-ref {task-ref}`
|
|
279
|
+
- 标准路径:`agent-infra-internal agent-client next-steps --skill plan-task --task-ref {task-ref}`
|
|
280
|
+
- 完整路径:`agent-infra-internal agent-client next-steps --skill review-analysis --task-ref {task-ref}`
|
|
265
281
|
|
|
266
282
|
```
|
|
267
283
|
任务 {task-id} 分析完成。
|
|
@@ -274,7 +290,7 @@ agent-infra-internal task-verify {task-id} analyze.completed --artifact {analysi
|
|
|
274
290
|
产出文件:
|
|
275
291
|
- 分析报告:.agents/workspace/active/{task-id}/{analysis-artifact}
|
|
276
292
|
|
|
277
|
-
下一步 -
|
|
293
|
+
下一步 - 按所选路径继续:
|
|
278
294
|
{next-step-commands}
|
|
279
295
|
```
|
|
280
296
|
|
|
@@ -292,7 +308,7 @@ agent-infra-internal task-verify {task-id} analyze.completed --artifact {analysi
|
|
|
292
308
|
|
|
293
309
|
## 停止
|
|
294
310
|
|
|
295
|
-
|
|
311
|
+
完成检查清单后,**立即停止**。等待用户调用上述所选路径的下一阶段。
|
|
296
312
|
|
|
297
313
|
## 注意事项
|
|
298
314
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-task
|
|
3
3
|
description: >
|
|
4
|
-
Implement code from the
|
|
5
|
-
Use when
|
|
4
|
+
Implement code from the selected lifecycle input and output a report.
|
|
5
|
+
Use when analysis or a technical plan is ready for the selected path, or code review found issues to fix.
|
|
6
6
|
Only invoke this skill automatically when the conversation includes a resolvable task reference.
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -11,16 +11,20 @@ description: >
|
|
|
11
11
|
|
|
12
12
|
If the entry operands contain `--orchestrated`, bind `{execution-flag}` to `--orchestrated` and forward it unchanged to the completed event; otherwise bind it to an empty value. Never infer it from `orchestration.json`, environment variables, or prior artifacts. Lifecycle events also require explicit trigger data: use `{trigger-initiator}=orchestrator` for orchestration and `model` otherwise; `{request-id}` is a stable single-line identifier for this task and artifact round, and `{reason-code}` is `user-request` for initial work and `review-finding` for fixes or decisions. Reuse the same values for started and completed.
|
|
13
13
|
|
|
14
|
-
Implement the
|
|
14
|
+
Implement from the input selected by the lifecycle path and produce `code.md` or `code-r{N}.md`. This skill supports initial implementation, fix mode based on `review-code` feedback, and human-decision-driven implementation.
|
|
15
15
|
|
|
16
16
|
## Boundary / Critical Rules
|
|
17
17
|
|
|
18
|
+
### Path and rework
|
|
19
|
+
|
|
20
|
+
This stage consumes only the canonical path fact parsed by core from the latest valid analysis artifact; a stage omitted by that path must not create an artifact. When another Changes Requested verdict follows one completed revision-review cycle in the same stage, classify the rework before the next executor artifact and bind it to the finding, source SHA, and stable task-fact digest. A round or filename change is not new evidence.
|
|
21
|
+
|
|
18
22
|
### Persisted Report Evidence
|
|
19
23
|
|
|
20
24
|
Before generating the implementation report, read `.agents/rules/evidence-reporting.md`. Successful tests record the command, target scope, status or structured result, actual result, and uncovered parts; failures, blocking conditions, or disputes retain a reproducible entry point, exact location, and decisive excerpt instead of complete successful stdout.
|
|
21
25
|
|
|
22
26
|
- When evaluating candidate qualification or `HD-N`, read `.agents/rules/decision-qualification.md`, audit normalized task constraints/candidates, and record the five qualification-audit tables in the implementation report; unknown or unconfirmed constraints must not automatically exclude a candidate
|
|
23
|
-
- Follow the
|
|
27
|
+
- Follow the lifecycle input selected by core: `analysis.md` / `analysis-r{N}.md` for the streamlined path, and `plan.md` / `plan-r{N}.md` for the standard or full path
|
|
24
28
|
- Before generating task or lifecycle Markdown that will be synchronized to an Issue, read `.agents/rules/sync-content-generation.md` and apply its producer-side constraints; the sync path does not parse or rewrite the body
|
|
25
29
|
- Read `.agents/rules/compatibility-policy.md` before implementation. Implement only the compatibility budget explicitly approved by the plan; never retain old branches, result contracts, or migration shims merely to be “safe”
|
|
26
30
|
- Fix mode verifies each finding of the latest `review-code` one by one: fix it if it holds, or rebut it and record it under unresolved if it is unfounded/hallucinated; do not expand to issues the review did not list; manual-validation items are out of scope
|
|
@@ -56,7 +60,7 @@ After prerequisites and mode are confirmed and before this round's first artifac
|
|
|
56
60
|
|
|
57
61
|
### 1. Verify Prerequisites
|
|
58
62
|
|
|
59
|
-
Require `task.md
|
|
63
|
+
Require `task.md`. Step 4 validates the lifecycle input selected by the chosen path; the skill must not require a plan artifact unconditionally.
|
|
60
64
|
|
|
61
65
|
### 2. Ensure the Task Branch
|
|
62
66
|
|
|
@@ -78,6 +82,8 @@ status=$?
|
|
|
78
82
|
echo "$result"
|
|
79
83
|
```
|
|
80
84
|
|
|
85
|
+
When `selection.disposition` is `reuse`, reuse `selection.artifact`, do not run started/init, modify code, or write a new artifact, and continue directly to completion verification and next-step guidance. Otherwise continue with the table below.
|
|
86
|
+
|
|
81
87
|
Dispatch by `$status` and `result.mode`:
|
|
82
88
|
|
|
83
89
|
- `0` + `"init"`: initial implementation; record `{code-artifact}` and `{code-round}`
|
|
@@ -90,11 +96,11 @@ Dispatch by `$status` and `result.mode`:
|
|
|
90
96
|
|
|
91
97
|
### 5. Read Structured Inputs
|
|
92
98
|
|
|
93
|
-
Use only the structured result from step 4: read the
|
|
99
|
+
Use only the structured result from step 4: read `{lifecycle-input-artifact}` from `inputs` (analysis for the streamlined path, plan otherwise) and, in fix mode, the selected review artifact. Use `next.name` as `{code-artifact}` and `next.round` as `{code-round}`. In decision mode, take the unified identity from `implementation_input`, `decision_id`, and `decision_evidence`; do not rescan or construct identities in the skill.
|
|
94
100
|
|
|
95
|
-
### 6. Read the
|
|
101
|
+
### 6. Read the Lifecycle Input
|
|
96
102
|
|
|
97
|
-
Extract implementation steps, files, test strategy, constraints, risks, and approved tradeoffs
|
|
103
|
+
Extract implementation steps, files, test strategy, constraints, risks, and approved tradeoffs from `{lifecycle-input-artifact}`. In decision mode, also read the `{input-id}` row and its `{decision-evidence}` record in task.md, and implement only that ruling's requested behavior change.
|
|
98
104
|
|
|
99
105
|
### 7. Implement the Code
|
|
100
106
|
|