@fitlab-ai/agent-infra 0.6.0 → 0.6.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +12 -12
  2. package/README.zh-CN.md +12 -12
  3. package/bin/cli.ts +5 -1
  4. package/dist/bin/cli.js +6 -1
  5. package/dist/lib/defaults.json +5 -4
  6. package/dist/lib/sandbox/config.js +25 -7
  7. package/dist/lib/sandbox/runtime-engines.js +27 -0
  8. package/dist/package.json +1 -1
  9. package/lib/defaults.json +5 -4
  10. package/lib/sandbox/config.ts +35 -7
  11. package/lib/sandbox/runtime-engines.ts +39 -0
  12. package/package.json +5 -3
  13. package/templates/.agents/README.en.md +8 -8
  14. package/templates/.agents/README.zh-CN.md +8 -8
  15. package/templates/{.claude → .agents}/hooks/check-version-format.sh +3 -3
  16. package/templates/.agents/rules/create-issue.github.en.md +6 -0
  17. package/templates/.agents/rules/create-issue.github.zh-CN.md +6 -0
  18. package/templates/.agents/rules/issue-fields.github.en.md +155 -0
  19. package/templates/.agents/rules/issue-fields.github.zh-CN.md +155 -0
  20. package/templates/.agents/rules/issue-pr-commands.github.en.md +1 -0
  21. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +1 -0
  22. package/templates/.agents/rules/issue-sync.github.en.md +2 -1
  23. package/templates/.agents/rules/issue-sync.github.zh-CN.md +2 -1
  24. package/templates/.agents/rules/release-commands.github.en.md +9 -3
  25. package/templates/.agents/rules/release-commands.github.zh-CN.md +9 -3
  26. package/templates/.agents/rules/task-management.en.md +17 -9
  27. package/templates/.agents/rules/task-management.zh-CN.md +17 -9
  28. package/templates/.agents/rules/testing-discipline.en.md +40 -0
  29. package/templates/.agents/rules/testing-discipline.zh-CN.md +40 -0
  30. package/templates/.agents/rules/version-stamp.en.md +29 -0
  31. package/templates/.agents/rules/version-stamp.zh-CN.md +29 -0
  32. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +143 -6
  33. package/templates/.agents/scripts/validate-artifact.js +32 -5
  34. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -0
  35. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -0
  36. package/templates/.agents/skills/analyze-task/config/verify.json +2 -0
  37. package/templates/.agents/skills/block-task/SKILL.en.md +3 -0
  38. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +3 -0
  39. package/templates/.agents/skills/block-task/config/verify.json +1 -0
  40. package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -0
  41. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -0
  42. package/templates/.agents/skills/cancel-task/config/verify.json +1 -0
  43. package/templates/.agents/skills/commit/SKILL.en.md +10 -0
  44. package/templates/.agents/skills/commit/SKILL.zh-CN.md +10 -0
  45. package/templates/.agents/skills/commit/config/verify.json +1 -0
  46. package/templates/.agents/skills/commit/reference/task-status-update.en.md +5 -0
  47. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +5 -0
  48. package/templates/.agents/skills/complete-task/SKILL.en.md +4 -0
  49. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +4 -0
  50. package/templates/.agents/skills/complete-task/config/verify.json +2 -0
  51. package/templates/.agents/skills/create-pr/SKILL.en.md +5 -1
  52. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +5 -1
  53. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  54. package/templates/.agents/skills/create-release-note/SKILL.en.md +8 -11
  55. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +8 -11
  56. package/templates/.agents/skills/create-task/SKILL.en.md +9 -0
  57. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +9 -0
  58. package/templates/.agents/skills/create-task/config/verify.json +1 -0
  59. package/templates/.agents/skills/implement-task/SKILL.en.md +16 -1
  60. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +16 -1
  61. package/templates/.agents/skills/implement-task/config/verify.json +2 -0
  62. package/templates/.agents/skills/import-codescan/config/verify.json +1 -0
  63. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -0
  64. package/templates/.agents/skills/import-issue/SKILL.en.md +10 -0
  65. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -0
  66. package/templates/.agents/skills/import-issue/config/verify.json +1 -0
  67. package/templates/.agents/skills/plan-task/SKILL.en.md +3 -0
  68. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +3 -0
  69. package/templates/.agents/skills/plan-task/config/verify.json +2 -0
  70. package/templates/.agents/skills/refine-task/SKILL.en.md +15 -1
  71. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +15 -1
  72. package/templates/.agents/skills/refine-task/config/verify.json +2 -0
  73. package/templates/.agents/skills/refine-task/reference/fix-workflow.en.md +9 -0
  74. package/templates/.agents/skills/refine-task/reference/fix-workflow.zh-CN.md +9 -0
  75. package/templates/.agents/skills/refine-task/reference/report-template.en.md +11 -0
  76. package/templates/.agents/skills/refine-task/reference/report-template.zh-CN.md +11 -0
  77. package/templates/.agents/skills/restore-task/SKILL.en.md +3 -0
  78. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +3 -0
  79. package/templates/.agents/skills/restore-task/config/verify.json +1 -0
  80. package/templates/.agents/skills/review-task/SKILL.en.md +16 -1
  81. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +16 -1
  82. package/templates/.agents/skills/review-task/config/verify.json +3 -0
  83. package/templates/.agents/skills/review-task/reference/output-templates.en.md +20 -5
  84. package/templates/.agents/skills/review-task/reference/output-templates.zh-CN.md +20 -5
  85. package/templates/.agents/skills/review-task/reference/report-template.en.md +13 -0
  86. package/templates/.agents/skills/review-task/reference/report-template.zh-CN.md +13 -0
  87. package/templates/.agents/skills/review-task/reference/review-criteria.en.md +18 -0
  88. package/templates/.agents/skills/review-task/reference/review-criteria.zh-CN.md +18 -0
  89. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +5 -4
  90. package/templates/.agents/templates/task.en.md +5 -0
  91. package/templates/.agents/templates/task.zh-CN.md +5 -0
  92. package/templates/.claude/settings.json +1 -1
  93. package/templates/.codex/hooks.json +17 -0
@@ -5,6 +5,18 @@ import spawn from "cross-spawn";
5
5
 
6
6
  const CHECK_TYPE = "platform-sync";
7
7
  const DEFAULT_RETRY_DELAYS_MS = [3000, 10000];
8
+ const FRONTMATTER_FIELD_MAP = {
9
+ priority: "Priority",
10
+ effort: "Effort",
11
+ start_date: "Start date",
12
+ target_date: "Target date"
13
+ };
14
+ const OPTION_LOCALIZATION = {
15
+ "紧急": "Urgent",
16
+ "高": "High",
17
+ "中": "Medium",
18
+ "低": "Low"
19
+ };
8
20
 
9
21
  let activeShared = null;
10
22
  let repoRoot = "";
@@ -107,6 +119,7 @@ export function check({ taskDir, config, artifactFile }, shared) {
107
119
  checkPrAssignee,
108
120
  checkSyncedRequirements,
109
121
  checkIssueType,
122
+ checkIssueFields,
110
123
  checkMilestone
111
124
  ];
112
125
 
@@ -326,6 +339,27 @@ function fetchRemoteData(context) {
326
339
  }
327
340
  }
328
341
 
342
+ let issueFields;
343
+ if (context.config.verify_issue_fields && context.hasPush) {
344
+ const [owner, name] = context.upstreamRepo.split("/");
345
+ const issueFieldsResult = withRetry(() => ghJson([
346
+ "api",
347
+ "graphql",
348
+ "-f",
349
+ `query=${ISSUE_FIELDS_QUERY}`,
350
+ "-F",
351
+ `owner=${owner}`,
352
+ "-F",
353
+ `name=${name}`,
354
+ "-F",
355
+ `number=${context.issueNumber}`
356
+ ], context.taskDir));
357
+
358
+ if (issueFieldsResult.ok) {
359
+ issueFields = normalizeIssueFields(issueFieldsResult.value);
360
+ }
361
+ }
362
+
329
363
  let prLabels = null;
330
364
  let prMilestone;
331
365
  let prAssignees;
@@ -377,6 +411,7 @@ function fetchRemoteData(context) {
377
411
  prComments,
378
412
  prLabels,
379
413
  issueType,
414
+ issueFields,
380
415
  prMilestone,
381
416
  prAssignees
382
417
  };
@@ -703,6 +738,45 @@ function checkIssueType(context, remoteData) {
703
738
  return null;
704
739
  }
705
740
 
741
+ function checkIssueFields(context, remoteData) {
742
+ if (!context.config.verify_issue_fields || !context.hasPush) {
743
+ return null;
744
+ }
745
+
746
+ if (remoteData.issueFields === undefined) {
747
+ return null;
748
+ }
749
+
750
+ for (const [metadataKey, fieldName] of Object.entries(FRONTMATTER_FIELD_MAP)) {
751
+ const expectedRaw = context.task.metadata[metadataKey];
752
+ if (isBlank(expectedRaw) || !remoteData.issueFields.pinnedNames.has(fieldName)) {
753
+ continue;
754
+ }
755
+
756
+ const actual = remoteData.issueFields.values.get(fieldName);
757
+ const expected = normalizeExpectedIssueField(metadataKey, expectedRaw);
758
+ if (!expected) {
759
+ continue;
760
+ }
761
+
762
+ if (!actual) {
763
+ return failResult(CHECK_TYPE,
764
+ `Issue #${context.issueNumber} field '${fieldName}' is missing, expected '${expected.value}'`,
765
+ "check_failed"
766
+ );
767
+ }
768
+
769
+ if (actual.kind !== expected.kind || actual.value !== expected.value) {
770
+ return failResult(CHECK_TYPE,
771
+ `Issue #${context.issueNumber} field '${fieldName}' is '${actual.value}', expected '${expected.value}'`,
772
+ "check_failed"
773
+ );
774
+ }
775
+ }
776
+
777
+ return null;
778
+ }
779
+
706
780
  function checkPrAssignee(context, remoteData) {
707
781
  if (!context.config.verify_pr_assignee || !context.hasPush || !context.prNumber) {
708
782
  return null;
@@ -886,6 +960,69 @@ function mapTaskTypeToIssueType(taskType) {
886
960
  return mapping[taskType] || "Task";
887
961
  }
888
962
 
963
+ const ISSUE_FIELDS_QUERY = `query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){issue(number:$number){issueType{name pinnedFields{__typename ... on IssueFieldSingleSelect{id name} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}} issueFieldValues(first:50){nodes{__typename ... on IssueFieldSingleSelectValue{name optionId field{... on IssueFieldSingleSelect{name}}} ... on IssueFieldDateValue{value field{... on IssueFieldDate{name}}} ... on IssueFieldTextValue{value field{... on IssueFieldText{name}}} ... on IssueFieldNumberValue{value field{... on IssueFieldNumber{name}}}}}}}}`;
964
+
965
+ function normalizeIssueFields(payload) {
966
+ const issue = payload?.data?.repository?.issue;
967
+ const pinnedFields = Array.isArray(issue?.issueType?.pinnedFields)
968
+ ? issue.issueType.pinnedFields
969
+ : [];
970
+ const values = Array.isArray(issue?.issueFieldValues?.nodes)
971
+ ? issue.issueFieldValues.nodes
972
+ : [];
973
+ const pinnedNames = new Set(
974
+ pinnedFields
975
+ .map((field) => typeof field?.name === "string" ? field.name : "")
976
+ .filter(Boolean)
977
+ );
978
+ const normalizedValues = new Map();
979
+
980
+ for (const value of values) {
981
+ const fieldName = value?.field?.name;
982
+ if (!fieldName) {
983
+ continue;
984
+ }
985
+
986
+ if (value.__typename === "IssueFieldSingleSelectValue") {
987
+ normalizedValues.set(fieldName, {
988
+ kind: "single-select",
989
+ value: normalizeOptionName(value.name)
990
+ });
991
+ } else if (value.__typename === "IssueFieldDateValue") {
992
+ normalizedValues.set(fieldName, {
993
+ kind: "date",
994
+ value: normalizeDateValue(value.value)
995
+ });
996
+ }
997
+ }
998
+
999
+ return { pinnedNames, values: normalizedValues };
1000
+ }
1001
+
1002
+ function normalizeExpectedIssueField(metadataKey, rawValue) {
1003
+ const value = String(rawValue || "").trim();
1004
+ if (!value) {
1005
+ return null;
1006
+ }
1007
+
1008
+ if (metadataKey === "start_date" || metadataKey === "target_date") {
1009
+ return { kind: "date", value: normalizeDateValue(value) };
1010
+ }
1011
+
1012
+ return { kind: "single-select", value: normalizeOptionName(value) };
1013
+ }
1014
+
1015
+ function normalizeOptionName(value) {
1016
+ const normalized = String(value || "").trim();
1017
+ return OPTION_LOCALIZATION[normalized] || normalized;
1018
+ }
1019
+
1020
+ function normalizeDateValue(value) {
1021
+ const normalized = String(value || "").trim();
1022
+ const match = normalized.match(/^\d{4}-\d{2}-\d{2}/);
1023
+ return match ? match[0] : normalized;
1024
+ }
1025
+
889
1026
  function arraysEqual(left, right) {
890
1027
  if (left.length !== right.length) {
891
1028
  return false;
@@ -928,14 +1065,14 @@ function computeExpectedInLabels(taskDir) {
928
1065
  return { ok: true, labels: Array.from(labels).sort(), mode: "mapped" };
929
1066
  }
930
1067
 
931
- const repoLabelsResult = ghJson([
1068
+ const repoLabelsResult = withRetry(() => ghJson([
932
1069
  "label",
933
1070
  "list",
934
1071
  "--limit",
935
1072
  "200",
936
1073
  "--json",
937
1074
  "name"
938
- ], taskDir);
1075
+ ], taskDir));
939
1076
  if (!repoLabelsResult.ok) {
940
1077
  return repoLabelsResult;
941
1078
  }
@@ -1015,10 +1152,10 @@ function resolveUpstreamRepo(taskDir) {
1015
1152
  return ownerRepo;
1016
1153
  }
1017
1154
 
1018
- const repoResult = ghJson([
1155
+ const repoResult = withRetry(() => ghJson([
1019
1156
  "api",
1020
1157
  `repos/${ownerRepo.value}`
1021
- ], taskDir);
1158
+ ], taskDir));
1022
1159
 
1023
1160
  if (!repoResult.ok) {
1024
1161
  return repoResult;
@@ -1053,12 +1190,12 @@ function resolveOwnerRepo(taskDir) {
1053
1190
  }
1054
1191
 
1055
1192
  function detectPermissions(upstreamRepo, taskDir) {
1056
- const permissionsResult = ghJson([
1193
+ const permissionsResult = withRetry(() => ghJson([
1057
1194
  "api",
1058
1195
  `repos/${upstreamRepo}`,
1059
1196
  "--jq",
1060
1197
  ".permissions"
1061
- ], taskDir);
1198
+ ], taskDir));
1062
1199
 
1063
1200
  if (!permissionsResult.ok) {
1064
1201
  return { hasTriage: false, hasPush: false };
@@ -22,12 +22,14 @@ const DEFAULT_REQUIRED_FIELDS = [
22
22
  "status",
23
23
  "created_at",
24
24
  "updated_at",
25
+ "agent_infra_version",
25
26
  "current_step",
26
27
  "assigned_to"
27
28
  ];
28
29
 
29
30
  const DEFAULT_FRESHNESS_MINUTES = 30;
30
31
  const DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?$/;
32
+ const AGENT_INFRA_VERSION_PATTERN = /^v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
31
33
  const ACTIVITY_LOG_PATTERN = /^- (\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?) — \*\*(.+?)\*\* by (.+?) — (.+)$/;
32
34
  const BRANCH_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
33
35
 
@@ -212,8 +214,24 @@ function checkTaskMeta({ taskDir, config }) {
212
214
  const metadata = task.metadata;
213
215
  const requiredFields = config.required_fields || DEFAULT_REQUIRED_FIELDS;
214
216
  const missingFields = requiredFields.filter((field) => isBlank(metadata[field]));
215
- if (missingFields.length > 0) {
216
- return failResult("task-meta", `Missing required fields: ${missingFields.join(", ")}`);
217
+ const blockingMissingFields = missingFields.filter((field) => field !== "agent_infra_version");
218
+ const warnings = [];
219
+ if (missingFields.includes("agent_infra_version")) {
220
+ warnings.push("field 'agent_infra_version' missing — historical task or skipped version stamp");
221
+ }
222
+ if (blockingMissingFields.length > 0) {
223
+ return failResult("task-meta", `Missing required fields: ${blockingMissingFields.join(", ")}`);
224
+ }
225
+
226
+ if (
227
+ !isBlank(metadata.agent_infra_version) &&
228
+ metadata.agent_infra_version !== "unknown" &&
229
+ !AGENT_INFRA_VERSION_PATTERN.test(metadata.agent_infra_version)
230
+ ) {
231
+ return failResult(
232
+ "task-meta",
233
+ `Invalid agent_infra_version: ${metadata.agent_infra_version}`
234
+ );
217
235
  }
218
236
 
219
237
  const invalidDates = ["created_at", "updated_at", "completed_at", "blocked_at", "cancelled_at"]
@@ -272,7 +290,12 @@ function checkTaskMeta({ taskDir, config }) {
272
290
  }
273
291
  }
274
292
 
275
- return passResult("task-meta", `Task metadata valid (${requiredFields.length} required fields checked)`);
293
+ const warningSuffix = warnings.length > 0 ? `; warnings: ${warnings.join("; ")}` : "";
294
+ return passResult(
295
+ "task-meta",
296
+ `Task metadata valid (${requiredFields.length} required fields checked${warningSuffix})`,
297
+ warnings
298
+ );
276
299
  }
277
300
 
278
301
  function validateTaskBranch(metadata) {
@@ -683,8 +706,12 @@ function buildSingleCheckSummary(status) {
683
706
  return "0 passed, 1 failed";
684
707
  }
685
708
 
686
- function passResult(type, message) {
687
- return { type, status: "pass", message };
709
+ function passResult(type, message, warnings = []) {
710
+ const result = { type, status: "pass", message };
711
+ if (warnings.length > 0) {
712
+ result.warnings = warnings;
713
+ }
714
+ return result;
688
715
  }
689
716
 
690
717
  function failResult(type, message, failType = "check_failed") {
@@ -11,6 +11,8 @@ description: "Analyze a task and produce a requirements document"
11
11
  - Base the analysis strictly on the existing requirements, context, and source information in `task.md`
12
12
  - After executing this skill, you **must** immediately update task status in task.md
13
13
 
14
+ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
15
+
14
16
  ## Steps
15
17
 
16
18
  ### 1. Verify Prerequisites
@@ -110,6 +112,7 @@ Update `.agents/workspace/active/{task-id}/task.md`:
110
112
  - `current_step`: requirement-analysis
111
113
  - `assigned_to`: {current AI agent}
112
114
  - `updated_at`: {current time}
115
+ - `agent_infra_version`: value from `.agents/rules/version-stamp.md`
113
116
  - Record the analysis artifact for this round: `{analysis-artifact}` (Round `{analysis-round}`)
114
117
  - If the task template contains a `## Analysis` section, update it to link to `{analysis-artifact}`
115
118
  - Mark requirement-analysis as complete in workflow progress and include the actual round when the task template supports it
@@ -11,6 +11,8 @@ description: "分析任务并输出需求分析文档"
11
11
  - 严格基于 `task.md` 中已有的需求、上下文和来源信息展开分析
12
12
  - 执行本技能后,你**必须**立即更新 task.md 中的任务状态
13
13
 
14
+ 版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
15
+
14
16
  ## 执行步骤
15
17
 
16
18
  ### 1. 验证前置条件
@@ -110,6 +112,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
110
112
  - `current_step`:requirement-analysis
111
113
  - `assigned_to`:{当前 AI 代理}
112
114
  - `updated_at`:{当前时间}
115
+ - `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
113
116
  - 记录本轮分析产物:`{analysis-artifact}`(Round `{analysis-round}`)
114
117
  - 如任务模板包含 `## 分析` 段落,更新为指向 `{analysis-artifact}` 的链接
115
118
  - 在工作流进度中标记 requirement-analysis 为已完成,并注明实际轮次(如果任务模板支持)
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to"
14
15
  ],
@@ -37,6 +38,7 @@
37
38
  "verify_comment_content": true,
38
39
  "verify_task_comment_content": true,
39
40
  "verify_issue_type": true,
41
+ "verify_issue_fields": false,
40
42
  "verify_milestone": true,
41
43
  "expected_status_label_key": "pendingDesignWork",
42
44
  "expected_comment_marker_key": "artifact"
@@ -17,6 +17,8 @@ description: "Mark a task as blocked and record the reason"
17
17
  - **Resource issues**: Missing access, waiting for external team, blocked by another task
18
18
  - **Decision needed**: Architecture decision pending, stakeholder approval required
19
19
 
20
+ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
21
+
20
22
  ## Steps
21
23
 
22
24
  ### 1. Verify Task Exists
@@ -47,6 +49,7 @@ Update `.agents/workspace/active/{task-id}/task.md`:
47
49
  - `status`: blocked
48
50
  - `blocked_at`: {current timestamp}
49
51
  - `updated_at`: {current timestamp}
52
+ - `agent_infra_version`: value from `.agents/rules/version-stamp.md`
50
53
  - **Append** to `## Activity Log` (do NOT overwrite previous entries):
51
54
  ```
52
55
  - {YYYY-MM-DD HH:mm:ss±HH:MM} — **Blocked** by {agent} — {one-line reason}
@@ -17,6 +17,8 @@ description: "标记任务为阻塞状态并记录原因"
17
17
  - **资源问题**:缺少访问权限、等待外部团队、被其他任务阻塞
18
18
  - **需要决策**:待定的架构决策、需要利益相关者批准
19
19
 
20
+ 版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
21
+
20
22
  ## 执行步骤
21
23
 
22
24
  ### 1. 验证任务存在
@@ -47,6 +49,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
47
49
  - `status`:blocked
48
50
  - `blocked_at`:{当前时间戳}
49
51
  - `updated_at`:{当前时间戳}
52
+ - `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
50
53
  - **追加**到 `## Activity Log`(不要覆盖之前的记录):
51
54
  ```
52
55
  - {YYYY-MM-DD HH:mm:ss±HH:MM} — **Blocked** by {agent} — {一行原因}
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to",
14
15
  "blocked_at"
@@ -11,6 +11,8 @@ description: "Cancel an unneeded task and move it"
11
11
  - Cancel only when the task no longer needs implementation, review, or follow-up work
12
12
  - When a valid `issue_number` exists, Issue sync is required
13
13
 
14
+ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
15
+
14
16
  ## Steps
15
17
 
16
18
  ### 1. Verify Task Exists
@@ -48,6 +50,7 @@ Update `task.md` in the task directory:
48
50
  - `cancelled_at`: {current timestamp}
49
51
  - `cancel_reason`: {cancellation reason}
50
52
  - `updated_at`: {current timestamp}
53
+ - `agent_infra_version`: value from `.agents/rules/version-stamp.md`
51
54
  - **Append** to `## Activity Log` (do NOT overwrite previous entries):
52
55
  ```
53
56
  - {YYYY-MM-DD HH:mm:ss±HH:MM} — **Cancelled** by {agent} — {one-line cancellation reason}
@@ -11,6 +11,8 @@ description: "取消不再需要的任务并转移"
11
11
  - 只有在确认该任务无需继续实现、审查或修复时才可取消
12
12
  - 有效 `issue_number` 存在时,Issue 同步属于必做项
13
13
 
14
+ 版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
15
+
14
16
  ## 执行步骤
15
17
 
16
18
  ### 1. 验证任务存在
@@ -48,6 +50,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
48
50
  - `cancelled_at`:{当前时间戳}
49
51
  - `cancel_reason`:{取消原因}
50
52
  - `updated_at`:{当前时间戳}
53
+ - `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
51
54
  - **追加**到 `## Activity Log`(不要覆盖之前记录):
52
55
  ```
53
56
  - {YYYY-MM-DD HH:mm:ss±HH:MM} — **Cancelled** by {agent} — {一行取消原因}
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to",
14
15
  "cancelled_at",
@@ -7,6 +7,16 @@ description: "Commit the current changes to Git"
7
7
 
8
8
  Create a Git commit without overwriting user work and update the related task state when needed.
9
9
 
10
+ When updating related `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
11
+
12
+ ## Common Rationalizations and Rebuttals
13
+
14
+ | Rationalization | Rebuttal |
15
+ |------|------|
16
+ | "The tests already ran earlier, so I do not need to rerun them." | The staged content is the current truth; before committing, re-check `git status` and `git diff` instead of relying on memory. |
17
+ | "`git add -A` is faster." | `git add -A` and `git add .` are forbidden; stage only explicitly listed files to avoid including unrelated changes. |
18
+ | "This file has a copyright header, but the year can wait." | If you changed it, update the copyright year using `date +%Y`; this is a hard pre-commit check. |
19
+
10
20
  ## 1. Check Local Modifications (CRITICAL)
11
21
 
12
22
  Before any edit, inspect:
@@ -7,6 +7,16 @@ description: "提交当前变更到 Git"
7
7
 
8
8
  在不覆盖用户本地工作的前提下创建 Git commit,并在需要时更新关联任务状态。
9
9
 
10
+ 更新关联 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
11
+
12
+ ## 常见违规借口与反驳
13
+
14
+ | 借口 | 反驳 |
15
+ |------|------|
16
+ | 「测试之前跑过了,不用重跑」 | 暂存内容是最新现实;提交前必须重新核对 `git status`/`git diff`,不能凭记忆。 |
17
+ | 「`git add -A` 更省事」 | 禁止 `git add -A`/`git add .`;只暂存明确列出的文件,避免带入无关改动。 |
18
+ | 「改了带版权头的文件,年份先不动」 | 改了就更新版权年份(动态取 `date +%Y`),这是提交前的硬性检查。 |
19
+
10
20
  ## 1. 检查本地修改(关键)
11
21
 
12
22
  在任何编辑前先检查:
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to"
14
15
  ]
@@ -2,6 +2,8 @@
2
2
 
3
3
  Read this file before choosing the post-commit task-state branch.
4
4
 
5
+ Before updating task metadata, read `.agents/rules/version-stamp.md` and refresh `agent_infra_version` together with `updated_at`.
6
+
5
7
  ## Update the Related Task State
6
8
 
7
9
  Get the current time first:
@@ -53,6 +55,7 @@ Next step - complete and archive the task:
53
55
 
54
56
  If more work is still pending:
55
57
  - update `updated_at` in `task.md`
58
+ - update `agent_infra_version` from `.agents/rules/version-stamp.md`
56
59
  - record what this commit finished
57
60
  - record what the next human or agent action is
58
61
 
@@ -61,6 +64,7 @@ If more work is still pending:
61
64
  If this commit hands work over to code review:
62
65
  - update `current_step` to `code-review`
63
66
  - update `updated_at`
67
+ - update `agent_infra_version` from `.agents/rules/version-stamp.md`
64
68
  - mark implementation as finished in the workflow state
65
69
 
66
70
  Required next-step commands:
@@ -76,6 +80,7 @@ Next step - code review:
76
80
 
77
81
  If the next step is Pull Request creation:
78
82
  - update `updated_at`
83
+ - update `agent_infra_version` from `.agents/rules/version-stamp.md`
79
84
  - record the PR plan in `task.md`
80
85
 
81
86
  Required next-step commands:
@@ -2,6 +2,8 @@
2
2
 
3
3
  在选择提交后的任务状态分支之前先读取本文件。
4
4
 
5
+ 更新任务元数据前,先读取 `.agents/rules/version-stamp.md`,并随 `updated_at` 一起刷新 `agent_infra_version`。
6
+
5
7
  ## 更新关联任务状态
6
8
 
7
9
  先获取当前时间:
@@ -53,6 +55,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
53
55
 
54
56
  如果仍有工作待完成:
55
57
  - 更新 `task.md` 中的 `updated_at`
58
+ - 按 `.agents/rules/version-stamp.md` 更新 `agent_infra_version`
56
59
  - 记录这次提交完成了什么
57
60
  - 记录下一位人类或 agent 需要继续做什么
58
61
 
@@ -61,6 +64,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
61
64
  如果这次提交把工作移交给代码审查:
62
65
  - 将 `current_step` 更新为 `code-review`
63
66
  - 更新 `updated_at`
67
+ - 按 `.agents/rules/version-stamp.md` 更新 `agent_infra_version`
64
68
  - 在工作流状态中标记实现阶段已完成
65
69
 
66
70
  必带下一步命令:
@@ -76,6 +80,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
76
80
 
77
81
  如果下一步是创建 Pull Request:
78
82
  - 更新 `updated_at`
83
+ - 按 `.agents/rules/version-stamp.md` 更新 `agent_infra_version`
79
84
  - 在 `task.md` 中记录 PR 计划
80
85
 
81
86
  必带下一步命令:
@@ -10,6 +10,8 @@ description: "Mark a task as completed and archive it"
10
10
  - This command updates task metadata AND physically moves the task directory
11
11
  - Do not move a task that has incomplete workflow steps unless forced
12
12
 
13
+ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
14
+
13
15
  ## Steps
14
16
 
15
17
  ### 1. Verify Task Exists
@@ -58,8 +60,10 @@ date "+%Y-%m-%d %H:%M:%S%:z"
58
60
 
59
61
  Update `.agents/workspace/active/{task-id}/task.md`:
60
62
  - `status`: completed
63
+ - `current_step`: completed
61
64
  - `completed_at`: {current timestamp}
62
65
  - `updated_at`: {current timestamp}
66
+ - `agent_infra_version`: value from `.agents/rules/version-stamp.md`
63
67
  - Mark all workflow steps as complete
64
68
  - Verify and check off all items in `## Completion Checklist` (change `- [ ]` to `- [x]`)
65
69
  - **Append** to `## Activity Log` (do NOT overwrite previous entries):
@@ -10,6 +10,8 @@ description: "标记任务完成并归档"
10
10
  - 本命令更新任务元数据并物理移动任务目录
11
11
  - 除非强制执行,不要转移有未完成工作流步骤的任务
12
12
 
13
+ 版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
14
+
13
15
  ## 执行步骤
14
16
 
15
17
  ### 1. 验证任务存在
@@ -58,8 +60,10 @@ date "+%Y-%m-%d %H:%M:%S%:z"
58
60
 
59
61
  更新 `.agents/workspace/active/{task-id}/task.md`:
60
62
  - `status`:completed
63
+ - `current_step`:completed
61
64
  - `completed_at`:{当前时间戳}
62
65
  - `updated_at`:{当前时间戳}
66
+ - `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
63
67
  - 标记所有工作流步骤为已完成
64
68
  - 逐项验证并勾选 `## 完成检查清单` 中的所有条目(将 `- [ ]` 改为 `- [x]`)
65
69
  - **追加**到 `## Activity Log`(不要覆盖之前的记录):
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to",
14
15
  "completed_at"
@@ -29,6 +30,7 @@
29
30
  "verify_task_comment_content": true,
30
31
  "sync_checked_requirements": true,
31
32
  "verify_issue_type": true,
33
+ "verify_issue_fields": false,
32
34
  "verify_milestone": true,
33
35
  "expected_comment_marker_key": "summary"
34
36
  }
@@ -7,6 +7,10 @@ description: "Create a Pull Request to a target branch"
7
7
 
8
8
  Create a Pull Request and, when task-related, sync the essential metadata and reviewer summary immediately.
9
9
 
10
+ ## Boundary / Critical Rules
11
+
12
+ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
13
+
10
14
  ## Execution Flow
11
15
 
12
16
  ### 1. Parse Command Arguments
@@ -72,7 +76,7 @@ Get the current time:
72
76
  date "+%Y-%m-%d %H:%M:%S%:z"
73
77
  ```
74
78
 
75
- If `{task-id}` is available, update task.md with `pr_number`, `updated_at`, and append the PR Created Activity Log entry including metadata-sync and summary results.
79
+ If `{task-id}` is available, update task.md with `pr_number`, `updated_at`, `agent_infra_version`, and append the PR Created Activity Log entry including metadata-sync and summary results.
76
80
 
77
81
  ### 9. Verification Gate
78
82
 
@@ -7,6 +7,10 @@ description: "创建 Pull Request 到目标分支"
7
7
 
8
8
  创建 Pull Request,并在与任务关联时立即补齐核心元数据和 reviewer 摘要。
9
9
 
10
+ ## 行为边界 / 关键规则
11
+
12
+ 版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
13
+
10
14
  ## 执行流程
11
15
 
12
16
  ### 1. 解析命令参数
@@ -72,7 +76,7 @@ description: "创建 Pull Request 到目标分支"
72
76
  date "+%Y-%m-%d %H:%M:%S%:z"
73
77
  ```
74
78
 
75
- 如果获取到了 `{task-id}`,更新 task.md 的 `pr_number`、`updated_at`,并追加 PR Created 的 Activity Log,记录元数据同步和摘要发布结果。
79
+ 如果获取到了 `{task-id}`,更新 task.md 的 `pr_number`、`updated_at`、`agent_infra_version`,并追加 PR Created 的 Activity Log,记录元数据同步和摘要发布结果。
76
80
 
77
81
  ### 9. 完成校验
78
82
 
@@ -9,6 +9,7 @@
9
9
  "status",
10
10
  "created_at",
11
11
  "updated_at",
12
+ "agent_infra_version",
12
13
  "current_step",
13
14
  "assigned_to"
14
15
  ]