@fitlab-ai/agent-infra 0.9.13 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/bin/cli.ts +26 -9
  2. package/dist/bin/cli.js +173 -157
  3. package/dist/bin/internal-cli.js +42 -21
  4. package/dist/lib/agent-client.js +5 -0
  5. package/dist/lib/internal/agent-client.js +5 -2
  6. package/dist/lib/internal/cli-route-inventory.js +152 -0
  7. package/dist/lib/internal/codex-lifecycle.js +9 -6
  8. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  9. package/dist/lib/internal/git-workflow.js +10 -6
  10. package/dist/lib/internal/platform-checks.js +16 -4
  11. package/dist/lib/internal/platform-comment.js +16 -4
  12. package/dist/lib/internal/platform-context.js +4 -1
  13. package/dist/lib/internal/platform-issue.js +12 -4
  14. package/dist/lib/internal/platform-metadata.js +88 -0
  15. package/dist/lib/internal/platform-pr-review.js +16 -3
  16. package/dist/lib/internal/platform-pr.js +24 -10
  17. package/dist/lib/internal/platform-release-notes.js +6 -3
  18. package/dist/lib/internal/platform-security.js +93 -0
  19. package/dist/lib/internal/pr-review-grade.js +14 -3
  20. package/dist/lib/internal/release-workflow.js +19 -5
  21. package/dist/lib/internal/sandbox-control.js +22 -5
  22. package/dist/lib/internal/task-activity.js +13 -4
  23. package/dist/lib/internal/task-artifact.js +186 -27
  24. package/dist/lib/internal/task-context.js +4 -1
  25. package/dist/lib/internal/task-create.js +48 -15
  26. package/dist/lib/internal/task-delivery.js +4 -1
  27. package/dist/lib/internal/task-event.js +4 -1
  28. package/dist/lib/internal/task-finalization.js +4 -1
  29. package/dist/lib/internal/task-invalidation.js +4 -1
  30. package/dist/lib/internal/task-ledger.js +12 -1
  31. package/dist/lib/internal/task-lifecycle.js +4 -1
  32. package/dist/lib/internal/task-operation-registry.js +421 -0
  33. package/dist/lib/internal/task-orchestration.js +12 -0
  34. package/dist/lib/internal/task-override.js +10 -3
  35. package/dist/lib/internal/task-qualification.js +90 -0
  36. package/dist/lib/internal/task-review.js +4 -1
  37. package/dist/lib/internal/task-short-id.js +11 -1
  38. package/dist/lib/internal/task-snapshot.js +4 -1
  39. package/dist/lib/internal/task-validate.js +7 -2
  40. package/dist/lib/internal/task-verify.js +5 -1
  41. package/dist/lib/internal/task-warning.js +8 -1
  42. package/dist/lib/platform/comment-safety.js +226 -0
  43. package/dist/lib/platform/github-provider.js +233 -6
  44. package/dist/lib/platform/issue-comments.js +146 -34
  45. package/dist/lib/platform/pr-change-report.js +6 -12
  46. package/dist/lib/platform/pr-summary.js +28 -7
  47. package/dist/lib/platform/provider-contract.d.ts +67 -1
  48. package/dist/lib/platform/provider-contract.js +6 -2
  49. package/dist/lib/platform/provider-validation.js +76 -3
  50. package/dist/lib/platform/pull-requests.js +115 -170
  51. package/dist/lib/platform/repository-metadata.js +377 -0
  52. package/dist/lib/platform/security-alerts.js +155 -0
  53. package/dist/lib/platform/verification-sync.js +33 -26
  54. package/dist/lib/process-data/index.js +7 -0
  55. package/dist/lib/run/index.js +5 -0
  56. package/dist/lib/sandbox/commands/control-status.js +22 -0
  57. package/dist/lib/sandbox/commands/create.js +32 -6
  58. package/dist/lib/sandbox/commands/ls.js +5 -0
  59. package/dist/lib/sandbox/commands/rm.js +827 -120
  60. package/dist/lib/sandbox/commands/show.js +16 -0
  61. package/dist/lib/sandbox/control/client.js +83 -9
  62. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  63. package/dist/lib/sandbox/control/container-identity.js +28 -31
  64. package/dist/lib/sandbox/control/executor.js +149 -14
  65. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  66. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  67. package/dist/lib/sandbox/control/server.js +305 -35
  68. package/dist/lib/sandbox/control/state.js +5 -3
  69. package/dist/lib/sandbox/control/task-view.js +183 -0
  70. package/dist/lib/sandbox/engines/authority.js +289 -0
  71. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  72. package/dist/lib/sandbox/index.js +5 -0
  73. package/dist/lib/sandbox/recovery.js +21 -1
  74. package/dist/lib/sandbox/workspace-view.js +2 -1
  75. package/dist/lib/sandbox/worktree-safety.js +4 -1
  76. package/dist/lib/server/index.js +8 -0
  77. package/dist/lib/task/artifact-lifecycle.js +42 -13
  78. package/dist/lib/task/artifact-operations.js +520 -0
  79. package/dist/lib/task/artifact-repair-intent.js +59 -0
  80. package/dist/lib/task/artifact-schema.js +135 -0
  81. package/dist/lib/task/capabilities.js +72 -1
  82. package/dist/lib/task/control-authority.js +4 -0
  83. package/dist/lib/task/create-service.js +103 -4
  84. package/dist/lib/task/create.js +25 -0
  85. package/dist/lib/task/events.js +186 -67
  86. package/dist/lib/task/index.js +11 -3
  87. package/dist/lib/task/local-artifact-finalization.js +75 -150
  88. package/dist/lib/task/orchestration.js +192 -52
  89. package/dist/lib/task/qualification-audit.js +490 -0
  90. package/dist/lib/task/qualification-confirmation.js +109 -0
  91. package/dist/lib/task/qualification-intents.js +148 -0
  92. package/dist/lib/task/review-artifacts.js +22 -23
  93. package/dist/lib/task/review-finalization.js +121 -4
  94. package/dist/lib/task/sections.js +6 -4
  95. package/dist/lib/task/verification-config.js +11 -0
  96. package/dist/lib/task/verification-engine.js +54 -4
  97. package/dist/lifecycle-build-manifest.json +3 -3
  98. package/lib/agent-client.ts +9 -0
  99. package/lib/internal/agent-client.ts +4 -2
  100. package/lib/internal/cli-route-inventory.ts +140 -0
  101. package/lib/internal/codex-lifecycle.ts +8 -6
  102. package/lib/internal/codex-sandbox-controller.ts +7 -2
  103. package/lib/internal/git-workflow.ts +9 -6
  104. package/lib/internal/platform-checks.ts +12 -4
  105. package/lib/internal/platform-comment.ts +12 -4
  106. package/lib/internal/platform-context.ts +3 -1
  107. package/lib/internal/platform-issue.ts +11 -4
  108. package/lib/internal/platform-metadata.ts +70 -0
  109. package/lib/internal/platform-pr-review.ts +14 -3
  110. package/lib/internal/platform-pr.ts +23 -10
  111. package/lib/internal/platform-release-notes.ts +5 -3
  112. package/lib/internal/platform-security.ts +83 -0
  113. package/lib/internal/pr-review-grade.ts +10 -3
  114. package/lib/internal/release-workflow.ts +17 -5
  115. package/lib/internal/sandbox-control.ts +19 -5
  116. package/lib/internal/task-activity.ts +12 -4
  117. package/lib/internal/task-artifact.ts +164 -25
  118. package/lib/internal/task-context.ts +3 -1
  119. package/lib/internal/task-create.ts +76 -15
  120. package/lib/internal/task-delivery.ts +3 -1
  121. package/lib/internal/task-event.ts +3 -1
  122. package/lib/internal/task-finalization.ts +3 -1
  123. package/lib/internal/task-invalidation.ts +3 -1
  124. package/lib/internal/task-ledger.ts +11 -1
  125. package/lib/internal/task-lifecycle.ts +3 -1
  126. package/lib/internal/task-operation-registry.ts +482 -0
  127. package/lib/internal/task-orchestration.ts +12 -0
  128. package/lib/internal/task-override.ts +9 -3
  129. package/lib/internal/task-qualification.ts +61 -0
  130. package/lib/internal/task-review.ts +3 -1
  131. package/lib/internal/task-short-id.ts +10 -1
  132. package/lib/internal/task-snapshot.ts +3 -1
  133. package/lib/internal/task-validate.ts +6 -2
  134. package/lib/internal/task-verify.ts +4 -1
  135. package/lib/internal/task-warning.ts +7 -1
  136. package/lib/platform/comment-safety.ts +250 -0
  137. package/lib/platform/github-provider.ts +229 -7
  138. package/lib/platform/issue-comments.ts +160 -35
  139. package/lib/platform/pr-change-report.ts +6 -12
  140. package/lib/platform/pr-summary.ts +27 -6
  141. package/lib/platform/provider-contract.ts +78 -3
  142. package/lib/platform/provider-validation.ts +85 -3
  143. package/lib/platform/pull-requests.ts +126 -178
  144. package/lib/platform/repository-metadata.ts +453 -0
  145. package/lib/platform/security-alerts.ts +191 -0
  146. package/lib/platform/verification-sync.ts +32 -28
  147. package/lib/process-data/index.ts +7 -0
  148. package/lib/run/index.ts +5 -0
  149. package/lib/sandbox/commands/control-status.ts +26 -0
  150. package/lib/sandbox/commands/create.ts +46 -6
  151. package/lib/sandbox/commands/ls.ts +7 -0
  152. package/lib/sandbox/commands/rm.ts +1000 -87
  153. package/lib/sandbox/commands/show.ts +16 -0
  154. package/lib/sandbox/control/client.ts +103 -9
  155. package/lib/sandbox/control/completed-reentry.ts +98 -0
  156. package/lib/sandbox/control/container-identity.ts +27 -43
  157. package/lib/sandbox/control/executor.ts +177 -12
  158. package/lib/sandbox/control/lifecycle.ts +629 -17
  159. package/lib/sandbox/control/native-file-lock.ts +209 -0
  160. package/lib/sandbox/control/protocol.ts +5 -2
  161. package/lib/sandbox/control/server.ts +319 -37
  162. package/lib/sandbox/control/state.ts +6 -3
  163. package/lib/sandbox/control/task-view.ts +240 -0
  164. package/lib/sandbox/engines/authority.ts +365 -0
  165. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  166. package/lib/sandbox/index.ts +7 -0
  167. package/lib/sandbox/recovery.ts +21 -1
  168. package/lib/sandbox/workspace-view.ts +9 -3
  169. package/lib/sandbox/worktree-safety.ts +4 -1
  170. package/lib/server/index.ts +10 -0
  171. package/lib/task/artifact-lifecycle.ts +38 -16
  172. package/lib/task/artifact-operations.ts +626 -0
  173. package/lib/task/artifact-repair-intent.ts +71 -0
  174. package/lib/task/artifact-schema.ts +192 -0
  175. package/lib/task/capabilities.ts +70 -1
  176. package/lib/task/control-authority.ts +11 -1
  177. package/lib/task/create-service.ts +131 -6
  178. package/lib/task/create.ts +27 -0
  179. package/lib/task/events.ts +161 -65
  180. package/lib/task/index.ts +16 -3
  181. package/lib/task/local-artifact-finalization.ts +87 -218
  182. package/lib/task/orchestration.ts +172 -49
  183. package/lib/task/qualification-audit.ts +599 -0
  184. package/lib/task/qualification-confirmation.ts +117 -0
  185. package/lib/task/qualification-intents.ts +150 -0
  186. package/lib/task/review-artifacts.ts +21 -22
  187. package/lib/task/review-finalization.ts +133 -4
  188. package/lib/task/sections.ts +6 -4
  189. package/lib/task/verification-config.ts +12 -0
  190. package/lib/task/verification-engine.ts +55 -4
  191. package/package.json +6 -1
  192. package/templates/.agents/rules/README.en.md +2 -0
  193. package/templates/.agents/rules/README.zh-CN.md +2 -0
  194. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  195. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  196. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  197. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  198. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  199. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  200. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  201. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  202. package/templates/.agents/rules/security-alerts.en.md +8 -8
  203. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  204. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  205. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  206. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  207. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  208. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  209. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  210. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  211. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  212. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  213. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  214. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  215. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  216. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  217. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  218. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  219. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  220. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  221. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  222. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  223. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  224. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -1
  225. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -1
  226. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  227. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  228. package/templates/.agents/skills/complete-task/SKILL.en.md +9 -22
  229. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +9 -22
  230. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  231. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  232. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  233. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  234. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  235. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  236. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  237. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  238. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  239. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  240. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  241. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  242. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  243. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  244. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  245. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  246. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  247. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  248. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  249. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  250. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  251. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  252. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  253. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  254. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  255. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  256. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  257. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  258. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  259. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  260. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  261. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  262. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  263. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  264. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  265. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  266. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -1
  267. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -1
  268. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  269. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  270. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  271. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  272. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  273. package/templates/.agents/templates/task.en.md +6 -0
  274. package/templates/.agents/templates/task.zh-CN.md +6 -0
  275. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  276. package/templates/.agents/scripts/security-alerts.sh +0 -31
  277. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  278. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  279. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  280. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -1,72 +1,21 @@
1
1
  import fs from 'node:fs';
2
- import { createHash } from 'node:crypto';
3
- import path from 'node:path';
4
2
  import { inspectDecisionDetailDuplicates, scanVisibleMarkdown } from './decision-details.js';
5
3
  import { parseArtifactName, validateCompletedArtifact } from './artifact-lifecycle.js';
6
4
  import { resolveTaskRef } from './resolve-ref.js';
5
+ import { expectedQualificationRelations, validateQualificationAudit } from './qualification-audit.js';
6
+ import { canonicalSemanticDigest, inspectArtifactPatterns, inspectArtifactStructure, sha256Content } from './artifact-operations.js';
7
+ import { getArtifactSchema } from './artifact-schema.js';
8
+ import { readArtifactRepairIntent, writeArtifactRepairIntent } from './artifact-repair-intent.js';
7
9
  const LOCAL_ARTIFACT_REQUIRED_SECTIONS = {
8
- analysis: [
9
- '需求来源', '需求理解', '相关文件', '影响评估', '技术风险',
10
- '工作量和复杂度评估', '状态核对'
11
- ],
12
- plan: [
13
- '问题理解', '约束条件', '方案对比', '技术方法', '实施步骤',
14
- '文件清单', '验证策略', '状态核对'
15
- ],
16
- code: [
17
- '实现输入', '变更文件', '关键代码说明', '测试结果', '与方案的差异',
18
- '供审查关注的内容', '状态核对', '证据原文'
19
- ]
10
+ analysis: getArtifactSchema('analysis').sections.map((section) => section.headings.zh),
11
+ plan: getArtifactSchema('plan').sections.map((section) => section.headings.zh),
12
+ code: getArtifactSchema('code').sections.map((section) => section.headings.zh)
20
13
  };
21
- const LOCAL_ARTIFACT_REQUIRED_PATTERNS = ['^\\$ '];
22
- function finalizationIntentRoot(repoRoot) {
23
- return path.join(repoRoot, '.agents', 'workspace', '.local-artifact-finalization-intents');
24
- }
25
- function finalizationIntentPath(repoRoot, taskId, family, artifact) {
26
- return path.join(finalizationIntentRoot(repoRoot), `${taskId}-${family}-${artifact}.json`);
27
- }
28
- function isFinalizationIntent(value) {
29
- if (!value || typeof value !== 'object' || Array.isArray(value))
30
- return false;
31
- const intent = value;
32
- return intent.version === 1
33
- && typeof intent.taskId === 'string' && intent.taskId.length > 0
34
- && (intent.family === 'analysis' || intent.family === 'plan' || intent.family === 'code')
35
- && typeof intent.artifact === 'string' && intent.artifact.length > 0
36
- && (intent.state === 'awaiting-repair' || intent.state === 'passed' || intent.state === 'consumed')
37
- && (intent.baselineSemanticDigest === null || (typeof intent.baselineSemanticDigest === 'string' && /^[a-f0-9]{64}$/.test(intent.baselineSemanticDigest)))
38
- && typeof intent.artifactSha256 === 'string' && /^[a-f0-9]{64}$/.test(intent.artifactSha256)
39
- && typeof intent.semanticDigest === 'string' && /^[a-f0-9]{64}$/.test(intent.semanticDigest)
40
- && (intent.state === 'awaiting-repair' ? intent.baselineSemanticDigest === intent.semanticDigest : true);
41
- }
42
14
  function readLocalArtifactFinalizationIntent(repoRoot, taskId, family, artifact) {
43
- const target = finalizationIntentPath(repoRoot, taskId, family, artifact);
44
- if (!fs.existsSync(target))
45
- return null;
46
- const value = JSON.parse(fs.readFileSync(target, 'utf8'));
47
- if (!isFinalizationIntent(value) || value.taskId !== taskId || value.family !== family || value.artifact !== artifact) {
48
- throw new Error('LOCAL_FINALIZATION_INTENT_INVALID: finalization provenance schema is invalid');
49
- }
50
- return value;
15
+ return readArtifactRepairIntent(repoRoot, taskId, family, artifact);
51
16
  }
52
17
  function writeLocalArtifactFinalizationIntent(repoRoot, value) {
53
- if (!isFinalizationIntent(value))
54
- throw new Error('LOCAL_FINALIZATION_INTENT_INVALID: finalization provenance schema is invalid');
55
- const directory = finalizationIntentRoot(repoRoot);
56
- fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
57
- const target = finalizationIntentPath(repoRoot, value.taskId, value.family, value.artifact);
58
- const temporary = `${target}.${process.pid}.${Date.now()}.tmp`;
59
- fs.writeFileSync(temporary, `${JSON.stringify(value)}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
60
- try {
61
- fs.renameSync(temporary, target);
62
- }
63
- catch (error) {
64
- try {
65
- fs.unlinkSync(temporary);
66
- }
67
- catch { /* preserve primary error */ }
68
- throw error;
69
- }
18
+ writeArtifactRepairIntent(repoRoot, value);
70
19
  }
71
20
  function consumeLocalArtifactFinalizationIntent(repoRoot, intent) {
72
21
  if (intent.state === 'consumed')
@@ -77,122 +26,88 @@ function consumeLocalArtifactFinalizationIntent(repoRoot, intent) {
77
26
  writeLocalArtifactFinalizationIntent(repoRoot, consumed);
78
27
  return consumed;
79
28
  }
80
- function requiredSections(family) {
81
- return LOCAL_ARTIFACT_REQUIRED_SECTIONS[family];
82
- }
83
- function lineNumber(content, offset) {
84
- return content.slice(0, offset).split('\n').length;
85
- }
86
- function sectionBody(content, heading) {
87
- const next = scanVisibleMarkdown(content).headings.find((candidate) => (candidate.start > heading.start && candidate.level <= 2));
88
- return content.slice(heading.end, next?.start ?? content.length);
89
- }
90
- function semanticDigest(content, candidate) {
91
- let normalized = content;
92
- if (candidate) {
93
- const raw = content.slice(candidate.start, candidate.end);
94
- const marker = raw.match(/([::])\s*$/);
95
- if (marker?.index !== undefined) {
96
- const canonical = raw.slice(0, marker.index) + raw.slice(marker.index + 1);
97
- normalized = `${content.slice(0, candidate.start)}${canonical}${content.slice(candidate.end)}`;
98
- }
99
- }
100
- return createHash('sha256').update(normalized, 'utf8').digest('hex');
101
- }
102
- function sha256Content(content) {
103
- return createHash('sha256').update(content, 'utf8').digest('hex');
104
- }
105
- function visibleSectionHeadings(content, section) {
106
- return scanVisibleMarkdown(content).headings.filter((heading) => (heading.level === 2 && heading.text === section));
107
- }
108
- function trailingPunctuationCandidates(content, section) {
109
- return scanVisibleMarkdown(content).headings.filter((heading) => (heading.level === 2 && (heading.text === `${section}:` || heading.text === `${section}:`)));
29
+ function localDiagnosticCode(code) {
30
+ const map = {
31
+ ARTIFACT_EMPTY: 'LOCAL_ARTIFACT_EMPTY',
32
+ ARTIFACT_MISSING_SECTION: 'LOCAL_ARTIFACT_MISSING_SECTION',
33
+ ARTIFACT_DUPLICATE_SECTION: 'LOCAL_ARTIFACT_DUPLICATE_SECTION',
34
+ ARTIFACT_HEADING_TRAILING_PUNCTUATION: 'LOCAL_SECTION_HEADING_TRAILING_PUNCTUATION'
35
+ };
36
+ return map[code] ?? 'LOCAL_STRUCTURAL_INVALID';
110
37
  }
111
- function diagnostic(code, message, content, heading, extra = {}) {
38
+ function localDiagnostic(item) {
39
+ const code = localDiagnosticCode(item.code);
40
+ if (!code)
41
+ return null;
112
42
  return {
113
- code, message, repairable: false,
114
- line: heading ? lineNumber(content, heading.start) : null,
115
- ...extra
43
+ code,
44
+ message: item.message,
45
+ repairable: item.repairable,
46
+ line: item.line,
47
+ ...(item.operation?.kind === 'replace-line'
48
+ ? { from: item.operation.from, to: item.operation.to, operation: 'replace-line' }
49
+ : {})
116
50
  };
117
51
  }
118
52
  function isStatusPattern(pattern) {
119
53
  return pattern === '^\\$ ';
120
54
  }
121
55
  function validateLocalArtifact(content, options) {
122
- const sections = options.requiredSections ?? requiredSections(options.family);
123
- const patterns = options.requiredPatterns ?? LOCAL_ARTIFACT_REQUIRED_PATTERNS;
56
+ const schema = getArtifactSchema(options.family);
57
+ const patterns = schema.requiredPatterns;
124
58
  const diagnostics = [];
125
- const candidates = [];
126
59
  const scanned = scanVisibleMarkdown(content);
127
- if (!content.trim()) {
128
- diagnostics.push(diagnostic('LOCAL_ARTIFACT_EMPTY', 'artifact is empty', content));
60
+ const structure = inspectArtifactStructure(content, schema);
61
+ for (const item of structure.diagnostics) {
62
+ const mapped = localDiagnostic(item);
63
+ if (mapped)
64
+ diagnostics.push(mapped);
129
65
  }
130
- for (const section of sections) {
131
- const exact = scanned.headings.filter((heading) => heading.level === 2 && heading.text === section);
132
- const punctuated = trailingPunctuationCandidates(content, section);
133
- if (exact.length > 1 || punctuated.length > 0 && exact.length > 0 || punctuated.length > 1) {
134
- const first = exact[1] ?? punctuated[0] ?? exact[0];
135
- diagnostics.push(diagnostic('LOCAL_ARTIFACT_DUPLICATE_SECTION', `required section '${section}' is duplicated or has an ambiguous punctuation variant`, content, first));
136
- }
137
- else if (exact.length === 0 && punctuated.length === 1) {
138
- candidates.push(punctuated[0]);
139
- }
140
- else if (exact.length === 0) {
141
- diagnostics.push(diagnostic('LOCAL_ARTIFACT_MISSING_SECTION', `required section '${section}' is missing`, content));
142
- }
143
- }
144
- const statusSection = sections.find((section) => section === '状态核对' || section.toLowerCase() === 'state check');
66
+ const statusSection = schema.sections.find((section) => section.id === 'state-check');
145
67
  if (statusSection) {
146
- const statusHeading = visibleSectionHeadings(content, statusSection)[0]
147
- ?? candidates.find((heading) => heading.text === `${statusSection}:` || heading.text === `${statusSection}:`);
68
+ const statusHeading = scanned.headings.find((heading) => (heading.level === 2 && [statusSection.headings.zh, statusSection.headings.en].some((name) => (heading.text === name || heading.text === `${name}:` || heading.text === `${name}:`))));
148
69
  if (statusHeading) {
149
- const body = sectionBody(content, statusHeading);
70
+ const next = scanned.headings.find((candidate) => candidate.start > statusHeading.start && candidate.level <= 2);
71
+ const body = content.slice(statusHeading.end, next?.start ?? content.length);
150
72
  for (const pattern of patterns.filter(isStatusPattern)) {
151
73
  if (!new RegExp(pattern, 'm').test(body)) {
152
- diagnostics.push(diagnostic('LOCAL_STATUS_COMMAND_MISSING', `status section '${statusSection}' is missing required command output`, content, statusHeading));
74
+ diagnostics.push({ code: 'LOCAL_STATUS_COMMAND_MISSING', message: `status section '${statusHeading.text}' is missing required command output`, repairable: false, line: content.slice(0, statusHeading.start).split('\n').length });
153
75
  }
154
76
  }
155
77
  }
156
78
  }
157
- for (const pattern of patterns.filter((item) => !isStatusPattern(item))) {
158
- if (!new RegExp(pattern, 'm').test(content)) {
159
- diagnostics.push(diagnostic('LOCAL_REQUIRED_PATTERN_MISSING', `artifact is missing required pattern '${pattern}'`, content));
160
- }
79
+ const patternInspection = inspectArtifactPatterns(content, {
80
+ ...schema,
81
+ requiredPatterns: patterns.filter((item) => !isStatusPattern(item))
82
+ });
83
+ for (const item of patternInspection.diagnostics) {
84
+ diagnostics.push({ code: 'LOCAL_REQUIRED_PATTERN_MISSING', message: item.message, repairable: false, line: null });
161
85
  }
162
86
  const decisionDetails = inspectDecisionDetailDuplicates(content);
163
87
  if (!decisionDetails.ok) {
164
- diagnostics.push(diagnostic('LOCAL_DECISION_DETAIL_DUPLICATE', decisionDetails.message, content, decisionDetails.duplicates[0]?.blocks[0]
165
- ? scanned.headings.find((heading) => heading.start === decisionDetails.duplicates[0].blocks[0].start)
166
- : undefined));
88
+ diagnostics.push({ code: 'LOCAL_DECISION_DETAIL_DUPLICATE', message: decisionDetails.message, repairable: false, line: null });
167
89
  }
168
- if (candidates.length === 1 && diagnostics.length === 0) {
169
- const candidate = candidates[0];
170
- const section = candidate.text.slice(0, -1);
171
- const repair = diagnostic('LOCAL_SECTION_HEADING_TRAILING_PUNCTUATION', `visible required H2 '${candidate.text}' may be normalized to '${section}'`, content, candidate, {
172
- repairable: true,
173
- from: candidate.text,
174
- to: section,
175
- operation: 'replace-line'
90
+ if (options.taskContent !== undefined) {
91
+ const expected = expectedQualificationRelations(options.taskContent, options.family);
92
+ if (!expected.ok) {
93
+ diagnostics.push({ code: 'LOCAL_QUALIFICATION_AUDIT_INVALID', message: `${expected.code}: ${expected.message}`, repairable: false, line: null });
94
+ }
95
+ const qualification = validateQualificationAudit(options.taskContent, content, {
96
+ family: options.family === 'analysis' ? 'analysis' : options.family === 'plan' ? 'plan' : 'code',
97
+ artifact: options.artifact,
98
+ expectedUpstreamRelations: expected.ok ? expected.relations : undefined
176
99
  });
177
- return {
178
- ok: false,
179
- family: options.family,
180
- semanticDigest: semanticDigest(content, candidate),
181
- repairable: true,
182
- diagnostics: [repair]
183
- };
184
- }
185
- if (candidates.length > 0) {
186
- for (const candidate of candidates) {
187
- const section = candidate.text.slice(0, -1);
188
- diagnostics.push(diagnostic('LOCAL_ARTIFACT_MISSING_SECTION', `required section '${section}' is missing and cannot be repaired while other structural defects exist`, content, candidate));
100
+ if (!qualification.ok) {
101
+ diagnostics.push({ code: 'LOCAL_QUALIFICATION_AUDIT_INVALID', message: `${qualification.code}: ${qualification.message}`, repairable: false, line: null });
189
102
  }
190
103
  }
104
+ const repairable = structure.repair !== null && diagnostics.length === 1 && diagnostics[0]?.repairable === true;
105
+ const semanticDigestValue = canonicalSemanticDigest(content, structure.repair);
191
106
  return {
192
107
  ok: diagnostics.length === 0,
193
108
  family: options.family,
194
- semanticDigest: semanticDigest(content),
195
- repairable: false,
109
+ semanticDigest: semanticDigestValue,
110
+ repairable,
196
111
  diagnostics
197
112
  };
198
113
  }
@@ -211,7 +126,7 @@ function provenanceFailure(request, resolved, content, artifactSha256, semanticD
211
126
  taskDir: resolved.taskDir,
212
127
  artifactSha256,
213
128
  semanticDigest: semanticDigestValue,
214
- diagnostics: [diagnostic(code, message, content)]
129
+ diagnostics: [{ code, message, repairable: false, line: null }]
215
130
  });
216
131
  }
217
132
  function finalizeLocalArtifact(request) {
@@ -238,10 +153,20 @@ function finalizeLocalArtifact(request) {
238
153
  taskId: resolved.taskId, taskDir: resolved.taskDir
239
154
  });
240
155
  }
156
+ let taskContent;
157
+ try {
158
+ taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
159
+ }
160
+ catch (error) {
161
+ return failedFinalization(request, { code: 'TASK_READ_FAILED', message: error instanceof Error ? error.message : String(error) }, {
162
+ taskId: resolved.taskId, taskDir: resolved.taskDir
163
+ });
164
+ }
241
165
  const result = validateLocalArtifact(content, {
242
166
  family: request.family,
243
167
  requiredSections: request.requiredSections,
244
- requiredPatterns: request.requiredPatterns
168
+ taskContent,
169
+ artifact: request.artifact
245
170
  });
246
171
  const artifactSha256 = sha256Content(content);
247
172
  let intent;
@@ -370,5 +295,5 @@ function finalizeLocalArtifact(request) {
370
295
  }
371
296
  };
372
297
  }
373
- export { LOCAL_ARTIFACT_REQUIRED_PATTERNS, LOCAL_ARTIFACT_REQUIRED_SECTIONS, consumeLocalArtifactFinalizationIntent, finalizeLocalArtifact, readLocalArtifactFinalizationIntent, semanticDigest, sha256Content, validateLocalArtifact };
298
+ export { LOCAL_ARTIFACT_REQUIRED_SECTIONS, consumeLocalArtifactFinalizationIntent, finalizeLocalArtifact, readLocalArtifactFinalizationIntent, canonicalSemanticDigest as semanticDigest, sha256Content, validateLocalArtifact };
374
299
  //# sourceMappingURL=local-artifact-finalization.js.map