@tea-agent/loop-agent 0.1.0-fe-test.0

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 (1050) hide show
  1. package/AGENTS.md +114 -0
  2. package/CHANGELOG.md +2283 -0
  3. package/README.md +177 -0
  4. package/bin/agent-worker.js +22 -0
  5. package/bin/loop-agent.js +57 -0
  6. package/dist/adapters/aimax.js +91 -0
  7. package/dist/adapters/context.js +32 -0
  8. package/dist/adapters/index.js +29 -0
  9. package/dist/adapters/loop-agent.js +192 -0
  10. package/dist/adapters/types.js +1 -0
  11. package/dist/application/context-usage/skill-resolution-stats.js +263 -0
  12. package/dist/application/dag/args.js +486 -0
  13. package/dist/application/dag/generate-task-dag.js +408 -0
  14. package/dist/application/dag/report-dag.js +14 -0
  15. package/dist/application/dag/run-dag.js +109 -0
  16. package/dist/application/dag/validate-dag.js +166 -0
  17. package/dist/application/evaluation/alias.js +184 -0
  18. package/dist/application/evaluation/budget.js +192 -0
  19. package/dist/application/evaluation/campaign-hash.js +47 -0
  20. package/dist/application/evaluation/campaign-matrix.js +372 -0
  21. package/dist/application/evaluation/campaign-scorecard.js +135 -0
  22. package/dist/application/evaluation/campaign.js +370 -0
  23. package/dist/application/evaluation/candidate-hash.js +75 -0
  24. package/dist/application/evaluation/candidate.js +69 -0
  25. package/dist/application/evaluation/corpus-hash.js +38 -0
  26. package/dist/application/evaluation/corpus.js +56 -0
  27. package/dist/application/evaluation/experiment.js +294 -0
  28. package/dist/application/evaluation/ignition.js +198 -0
  29. package/dist/application/evaluation/integrity-audit.js +162 -0
  30. package/dist/application/evaluation/outer-loop.js +132 -0
  31. package/dist/application/evaluation/pi-cell-executor.js +39 -0
  32. package/dist/application/evaluation/private-verifier.js +46 -0
  33. package/dist/application/evaluation/promotion-policy.js +151 -0
  34. package/dist/application/evaluation/proposer.js +98 -0
  35. package/dist/application/evaluation/replay.js +289 -0
  36. package/dist/application/evaluation/types.js +652 -0
  37. package/dist/application/loop/run-action.js +19 -0
  38. package/dist/application/task-lifecycle/advance.js +1204 -0
  39. package/dist/application/task-lifecycle/gates.js +130 -0
  40. package/dist/application/task-lifecycle/index.js +7 -0
  41. package/dist/application/task-lifecycle/observe.js +424 -0
  42. package/dist/application/task-lifecycle/plan-transitions.js +251 -0
  43. package/dist/application/task-lifecycle/recommendations.js +180 -0
  44. package/dist/application/task-lifecycle/record.js +73 -0
  45. package/dist/application/task-lifecycle/types.js +1 -0
  46. package/dist/build-stamp.json +6 -0
  47. package/dist/cli/catalog.js +24 -0
  48. package/dist/cli/command-definitions.js +659 -0
  49. package/dist/cli/help.js +56 -0
  50. package/dist/cli/index.js +5 -0
  51. package/dist/cli/program.js +647 -0
  52. package/dist/cli/router.js +13 -0
  53. package/dist/cli/update/init-surface-notifier.js +167 -0
  54. package/dist/cli/update/notifier.js +117 -0
  55. package/dist/cli/update/npm-client.js +151 -0
  56. package/dist/cli/update/policy.js +92 -0
  57. package/dist/cli/update/runtime-activity.js +29 -0
  58. package/dist/cli/update/state.js +68 -0
  59. package/dist/cli-governance/active-residue-check.js +38 -0
  60. package/dist/cli.js +57 -0
  61. package/dist/commands/client-recovery.js +1373 -0
  62. package/dist/commands/closeout.js +13 -0
  63. package/dist/commands/coverage-audit.js +14 -0
  64. package/dist/commands/coverage-report.js +50 -0
  65. package/dist/commands/cursor-prompt.js +182 -0
  66. package/dist/commands/dag-approve.js +142 -0
  67. package/dist/commands/dag-final-verification.js +76 -0
  68. package/dist/commands/dag-init-hybrid.js +57 -0
  69. package/dist/commands/dag-reconcile-run.js +5 -0
  70. package/dist/commands/dag-reconcile-tasks.js +51 -0
  71. package/dist/commands/dag-reject.js +91 -0
  72. package/dist/commands/dag-report.js +76 -0
  73. package/dist/commands/dag-request-interrupt.js +20 -0
  74. package/dist/commands/dag-rerun-task.js +19 -0
  75. package/dist/commands/dag-rerun.js +111 -0
  76. package/dist/commands/dag-resume.js +35 -0
  77. package/dist/commands/dag-run-task.js +12 -0
  78. package/dist/commands/dag-validate.js +20 -0
  79. package/dist/commands/dag-workflow-compile.js +91 -0
  80. package/dist/commands/dag-workflow-plan.js +130 -0
  81. package/dist/commands/dag-workflow-validate.js +66 -0
  82. package/dist/commands/delegate.js +130 -0
  83. package/dist/commands/docs-archive.js +5 -0
  84. package/dist/commands/docs-audit.js +6 -0
  85. package/dist/commands/doctor.js +283 -0
  86. package/dist/commands/eval.js +1398 -0
  87. package/dist/commands/examples.js +90 -0
  88. package/dist/commands/goal.js +92 -0
  89. package/dist/commands/handoff-check.js +5 -0
  90. package/dist/commands/harvest.js +44 -0
  91. package/dist/commands/import-prd.js +81 -0
  92. package/dist/commands/init-upgrade.js +3085 -0
  93. package/dist/commands/init.js +3630 -0
  94. package/dist/commands/inspect.js +11 -0
  95. package/dist/commands/instructions.js +223 -0
  96. package/dist/commands/knowledge.js +162 -0
  97. package/dist/commands/loop-benchmark.js +72 -0
  98. package/dist/commands/loop.js +251 -0
  99. package/dist/commands/new-task.js +5 -0
  100. package/dist/commands/operator.js +44 -0
  101. package/dist/commands/pi-prompt.js +174 -0
  102. package/dist/commands/pi-reuse-benchmark.js +153 -0
  103. package/dist/commands/plan-list.js +5 -0
  104. package/dist/commands/plan.js +50 -0
  105. package/dist/commands/promote-run.js +29 -0
  106. package/dist/commands/reference-index.js +16 -0
  107. package/dist/commands/run-dag-progress.js +123 -0
  108. package/dist/commands/run-dag.js +22 -0
  109. package/dist/commands/spine.js +38 -0
  110. package/dist/commands/stats.js +113 -0
  111. package/dist/commands/status.js +57 -0
  112. package/dist/commands/study-init.js +192 -0
  113. package/dist/commands/task-advance.js +366 -0
  114. package/dist/commands/task-contract.js +269 -0
  115. package/dist/commands/task-source-prepare.js +479 -0
  116. package/dist/commands/task-status.js +133 -0
  117. package/dist/commands/workflow.js +259 -0
  118. package/dist/commands/worktree-create.js +31 -0
  119. package/dist/commands/worktree-list.js +5 -0
  120. package/dist/commands/worktree-remove.js +26 -0
  121. package/dist/executors/config-core.js +5 -0
  122. package/dist/executors/config.js +2 -0
  123. package/dist/executors/dag-pi-executor.js +1277 -0
  124. package/dist/executors/dag-static-executor.js +42 -0
  125. package/dist/executors/dag.js +3 -0
  126. package/dist/executors/index.js +6 -0
  127. package/dist/executors/model-routing.js +71 -0
  128. package/dist/executors/pi-defaults.js +9 -0
  129. package/dist/executors/pi-event-serializer.js +65 -0
  130. package/dist/executors/pi-executor.js +981 -0
  131. package/dist/executors/pi-playwright-cli-tool.js +1006 -0
  132. package/dist/executors/pi-prompt-transport.js +198 -0
  133. package/dist/executors/pi-reuse-benchmark.js +316 -0
  134. package/dist/executors/pi-runtime-reuse.js +29 -0
  135. package/dist/executors/pi-sdk-executor.js +722 -0
  136. package/dist/executors/pi-sdk.js +1 -0
  137. package/dist/executors/pi-writer-tool-policy.js +266 -0
  138. package/dist/executors/pi.js +3 -0
  139. package/dist/executors/playwright-cli-launcher.js +63 -0
  140. package/dist/executors/process-tree.js +33 -0
  141. package/dist/executors/shell-executor.js +3055 -0
  142. package/dist/executors/shell-presets.js +99 -0
  143. package/dist/executors/shell-verification.js +262 -0
  144. package/dist/executors/shell-write-guard.js +543 -0
  145. package/dist/executors/shell.js +3 -0
  146. package/dist/executors/static.js +1 -0
  147. package/dist/governance/checks.js +437 -0
  148. package/dist/governance/document-index-closure.js +164 -0
  149. package/dist/governance/exec-plans.js +549 -0
  150. package/dist/governance/harness.js +9 -0
  151. package/dist/governance/index.js +3 -0
  152. package/dist/governance/manifest-types.js +254 -0
  153. package/dist/governance/manifest.js +2 -0
  154. package/dist/governance/path-guard.js +69 -0
  155. package/dist/governance/path-guards.js +2 -0
  156. package/dist/governance/profiles.js +3 -0
  157. package/dist/governance/requirement-coverage.js +425 -0
  158. package/dist/governance/skill-safety.js +135 -0
  159. package/dist/governance/spine-audit.js +155 -0
  160. package/dist/infrastructure/evaluation/alias-store.js +199 -0
  161. package/dist/infrastructure/evaluation/campaign-store.js +154 -0
  162. package/dist/infrastructure/evaluation/candidate-store.js +439 -0
  163. package/dist/infrastructure/evaluation/corpus-store.js +181 -0
  164. package/dist/infrastructure/evaluation/experiment-store.js +124 -0
  165. package/dist/infrastructure/evaluation/ignition-store.js +82 -0
  166. package/dist/infrastructure/evaluation/private-verifier-store.js +145 -0
  167. package/dist/infrastructure/evaluation/proposer-store.js +78 -0
  168. package/dist/infrastructure/evaluation/store.js +40 -0
  169. package/dist/infrastructure/harness/active-residue-policy.js +73 -0
  170. package/dist/infrastructure/harness/artifact-store.js +72 -0
  171. package/dist/infrastructure/harness/atomic-write.js +50 -0
  172. package/dist/infrastructure/harness/completed-facts-guard.js +40 -0
  173. package/dist/infrastructure/harness/loop-action-store.js +20 -0
  174. package/dist/infrastructure/harness/loop-store.js +41 -0
  175. package/dist/infrastructure/harness/one-shot-run-store.js +94 -0
  176. package/dist/infrastructure/harness/task-store.js +108 -0
  177. package/dist/records/closeout.js +2 -0
  178. package/dist/records/harvest.js +215 -0
  179. package/dist/records/index.js +3 -0
  180. package/dist/records/one-shot-runs.js +386 -0
  181. package/dist/records/promotion.js +200 -0
  182. package/dist/shared/artifacts-core.js +107 -0
  183. package/dist/shared/artifacts.js +2 -0
  184. package/dist/shared/context-files.js +32 -0
  185. package/dist/shared/context.js +2 -0
  186. package/dist/shared/copy-dir.js +17 -0
  187. package/dist/shared/git-progress.js +172 -0
  188. package/dist/shared/index.js +5 -0
  189. package/dist/shared/logger.js +17 -0
  190. package/dist/shared/one-shot-prompt-args.js +98 -0
  191. package/dist/shared/openspec-spec.js +125 -0
  192. package/dist/shared/operator/capabilities.js +2659 -0
  193. package/dist/shared/operator/command-lifecycle.js +94 -0
  194. package/dist/shared/operator/envelope.js +59 -0
  195. package/dist/shared/operator/index.js +5 -0
  196. package/dist/shared/operator/registry.js +38 -0
  197. package/dist/shared/operator/types.js +5 -0
  198. package/dist/shared/output-truncation.js +37 -0
  199. package/dist/shared/package-metadata.js +530 -0
  200. package/dist/shared/path-refs.js +31 -0
  201. package/dist/shared/pi-retry-settings.js +23 -0
  202. package/dist/shared/playwright-cli-command-policy.js +41 -0
  203. package/dist/shared/preview.js +39 -0
  204. package/dist/shared/prompts.js +26 -0
  205. package/dist/shared/reference-context.js +264 -0
  206. package/dist/shared/resilient-git.js +133 -0
  207. package/dist/shared/runtime-activity.js +6 -0
  208. package/dist/shared/timeout-policy.js +24 -0
  209. package/dist/shared/timeout.js +1 -0
  210. package/dist/shared/types.js +5 -0
  211. package/dist/sidecars/cursor-prompt/executor.js +428 -0
  212. package/dist/sidecars/cursor-prompt/index.js +3 -0
  213. package/dist/sidecars/cursor-prompt/stream.js +121 -0
  214. package/dist/task/config-types.js +235 -0
  215. package/dist/task/config.js +2 -0
  216. package/dist/task/contract/adopt.js +166 -0
  217. package/dist/task/contract/apply.js +326 -0
  218. package/dist/task/contract/canonicalize.js +60 -0
  219. package/dist/task/contract/constants.js +30 -0
  220. package/dist/task/contract/diff.js +177 -0
  221. package/dist/task/contract/hash.js +42 -0
  222. package/dist/task/contract/import-revision.js +96 -0
  223. package/dist/task/contract/index.js +17 -0
  224. package/dist/task/contract/journal.js +155 -0
  225. package/dist/task/contract/lock.js +153 -0
  226. package/dist/task/contract/observe.js +296 -0
  227. package/dist/task/contract/paths.js +19 -0
  228. package/dist/task/contract/project.js +185 -0
  229. package/dist/task/contract/recover.js +312 -0
  230. package/dist/task/contract/request-ledger.js +37 -0
  231. package/dist/task/contract/schema.js +153 -0
  232. package/dist/task/contract/transaction.js +160 -0
  233. package/dist/task/contract/types.js +1 -0
  234. package/dist/task/contract/validate-draft.js +106 -0
  235. package/dist/task/dag-source-paths.js +50 -0
  236. package/dist/task/delegate.js +208 -0
  237. package/dist/task/frontend-preflight.js +131 -0
  238. package/dist/task/frontend-project-capability.js +570 -0
  239. package/dist/task/goal-audit.js +51 -0
  240. package/dist/task/goal-policy.js +8 -0
  241. package/dist/task/goal.js +3 -0
  242. package/dist/task/ids.js +1 -0
  243. package/dist/task/index.js +12 -0
  244. package/dist/task/lifecycle.js +1 -0
  245. package/dist/task/operator/capabilities.js +6 -0
  246. package/dist/task/operator/envelope.js +2 -0
  247. package/dist/task/operator/index.js +5 -0
  248. package/dist/task/operator/registry.js +2 -0
  249. package/dist/task/operator/types.js +1 -0
  250. package/dist/task/paths.js +1 -0
  251. package/dist/task/read-model.js +140 -0
  252. package/dist/task/runtime.js +708 -0
  253. package/dist/task/source-prepare/artifact-meta.js +137 -0
  254. package/dist/task/source-prepare/build-draft.js +232 -0
  255. package/dist/task/source-prepare/completeness.js +248 -0
  256. package/dist/task/source-prepare/index.js +10 -0
  257. package/dist/task/source-prepare/parse-intent.js +496 -0
  258. package/dist/task/source-prepare/path-policy.js +197 -0
  259. package/dist/task/source-prepare/placeholder-paths.js +77 -0
  260. package/dist/task/source-prepare/prepare.js +920 -0
  261. package/dist/task/source-prepare/reference-integrity.js +290 -0
  262. package/dist/task/source-prepare/semantic-intake.js +717 -0
  263. package/dist/task/source-prepare/types.js +7 -0
  264. package/dist/task/source-references.js +228 -0
  265. package/dist/task/source-state.js +1 -0
  266. package/dist/task/state.js +41 -0
  267. package/dist/task/subagent-guidance.js +1 -0
  268. package/dist/task/task-demand-routing.js +443 -0
  269. package/dist/task/workflow-state-types.js +92 -0
  270. package/dist/task/worktree-cleanup.js +140 -0
  271. package/dist/task/worktree.js +388 -0
  272. package/dist/verification/maven/cache.js +142 -0
  273. package/dist/verification/maven/index.js +120 -0
  274. package/dist/verification/maven/plan-commands.js +421 -0
  275. package/dist/verification/maven/pom-static.js +136 -0
  276. package/dist/verification/maven/scope-resolve.js +153 -0
  277. package/dist/verification/maven/stale.js +130 -0
  278. package/dist/verification/maven/types.js +23 -0
  279. package/dist/verification/maven/workspace-graph.js +322 -0
  280. package/dist/worker/cli.js +957 -0
  281. package/dist/worker/closeout/apply.js +73 -0
  282. package/dist/worker/closeout/preview.js +30 -0
  283. package/dist/worker/console/app-data.js +316 -0
  284. package/dist/worker/console/chat/artifact-card.js +30 -0
  285. package/dist/worker/console/chat/assistant-content.js +121 -0
  286. package/dist/worker/console/chat/chat-event-store.js +981 -0
  287. package/dist/worker/console/chat/chat-ui-policy.js +25 -0
  288. package/dist/worker/console/chat/compaction-errors.js +64 -0
  289. package/dist/worker/console/chat/composer-draft-store.js +45 -0
  290. package/dist/worker/console/chat/context-panel.js +54 -0
  291. package/dist/worker/console/chat/contract-apply-receipt-store.js +174 -0
  292. package/dist/worker/console/chat/explore-tools.js +299 -0
  293. package/dist/worker/console/chat/human-gate-card.js +45 -0
  294. package/dist/worker/console/chat/interview-adapter.js +149 -0
  295. package/dist/worker/console/chat/mcp-inventory.js +221 -0
  296. package/dist/worker/console/chat/model-resolver.js +215 -0
  297. package/dist/worker/console/chat/operation-card.js +92 -0
  298. package/dist/worker/console/chat/pi-console-config.js +376 -0
  299. package/dist/worker/console/chat/pi-runtime.js +2446 -0
  300. package/dist/worker/console/chat/repo-browser.js +140 -0
  301. package/dist/worker/console/chat/repo-walk.js +125 -0
  302. package/dist/worker/console/chat/resource-loader.js +59 -0
  303. package/dist/worker/console/chat/resource-preferences-store.js +152 -0
  304. package/dist/worker/console/chat/routes.js +3137 -0
  305. package/dist/worker/console/chat/runtime-context.js +102 -0
  306. package/dist/worker/console/chat/runtime-selection.js +96 -0
  307. package/dist/worker/console/chat/semantic-activity.js +489 -0
  308. package/dist/worker/console/chat/session-store.js +484 -0
  309. package/dist/worker/console/chat/shortcuts.js +217 -0
  310. package/dist/worker/console/chat/tool-adapter.js +131 -0
  311. package/dist/worker/console/chat/tool-preview.js +247 -0
  312. package/dist/worker/console/chat/tools.js +212 -0
  313. package/dist/worker/console/chat/turn-execution-registry.js +82 -0
  314. package/dist/worker/console/chat/turn-process.js +346 -0
  315. package/dist/worker/console/chat/usage.js +165 -0
  316. package/dist/worker/console/chat/workspace-landing.js +103 -0
  317. package/dist/worker/console/dag-confirmation.js +347 -0
  318. package/dist/worker/console/dag-execution-receipt.js +393 -0
  319. package/dist/worker/console/doctor.js +230 -0
  320. package/dist/worker/console/draft-store.js +158 -0
  321. package/dist/worker/console/harness-pi-model-matrix.js +137 -0
  322. package/dist/worker/console/human-gate-token.js +130 -0
  323. package/dist/worker/console/index.js +17 -0
  324. package/dist/worker/console/inspect-split.js +82 -0
  325. package/dist/worker/console/interview/assessment.js +67 -0
  326. package/dist/worker/console/interview/grill-me.js +277 -0
  327. package/dist/worker/console/interview/session.js +100 -0
  328. package/dist/worker/console/interview/tools.js +109 -0
  329. package/dist/worker/console/loopback.js +16 -0
  330. package/dist/worker/console/mutation-gate-receipt-store.js +184 -0
  331. package/dist/worker/console/night-aux-ticker.js +146 -0
  332. package/dist/worker/console/observe-health-match.js +179 -0
  333. package/dist/worker/console/observe-link.js +42 -0
  334. package/dist/worker/console/open-browser.js +134 -0
  335. package/dist/worker/console/operation-run-facts.js +190 -0
  336. package/dist/worker/console/operation-runner.js +353 -0
  337. package/dist/worker/console/operation-sse.js +184 -0
  338. package/dist/worker/console/operation-store.js +169 -0
  339. package/dist/worker/console/operation-wait.js +355 -0
  340. package/dist/worker/console/operator-actions.js +3768 -0
  341. package/dist/worker/console/operator-selection.js +105 -0
  342. package/dist/worker/console/operator-surface-health.js +24 -0
  343. package/dist/worker/console/operator-user-error.js +45 -0
  344. package/dist/worker/console/pi-readiness.js +288 -0
  345. package/dist/worker/console/prd-identity.js +102 -0
  346. package/dist/worker/console/prd-intake-bridge.js +441 -0
  347. package/dist/worker/console/prd-reference-discovery.js +124 -0
  348. package/dist/worker/console/recovery-cta.js +320 -0
  349. package/dist/worker/console/recovery-error-copy.js +198 -0
  350. package/dist/worker/console/recovery-selection.js +107 -0
  351. package/dist/worker/console/repo-fingerprint.js +35 -0
  352. package/dist/worker/console/resolve-dag-run-for-task.js +115 -0
  353. package/dist/worker/console/resource-loader.js +95 -0
  354. package/dist/worker/console/routes.js +475 -0
  355. package/dist/worker/console/security.js +170 -0
  356. package/dist/worker/console/server.js +357 -0
  357. package/dist/worker/console/sibling-controller.js +33 -0
  358. package/dist/worker/console/static/assets/abnfDiagram-N423BO3Z-BmOEx0gA.js +1 -0
  359. package/dist/worker/console/static/assets/arc-BGiVVe8b.js +1 -0
  360. package/dist/worker/console/static/assets/architectureDiagram-T3A2C74G-nDdu4rgJ.js +36 -0
  361. package/dist/worker/console/static/assets/blockDiagram-VBNYF7ZC-Bb5u0BWf.js +132 -0
  362. package/dist/worker/console/static/assets/c4Diagram-5PPSVZJV-BlhC0j94.js +10 -0
  363. package/dist/worker/console/static/assets/channel-Tl-FkUqr.js +1 -0
  364. package/dist/worker/console/static/assets/chunk-2GRJ4B5K-Ai8_qQXI.js +1 -0
  365. package/dist/worker/console/static/assets/chunk-2Q5K7J3B-B9gyCjqX.js +1 -0
  366. package/dist/worker/console/static/assets/chunk-5RXB4S5H-Bzbj3zGH.js +231 -0
  367. package/dist/worker/console/static/assets/chunk-5VM5RSS4-BT415PvT.js +15 -0
  368. package/dist/worker/console/static/assets/chunk-6Q2QTUOP-D_A5_5QL.js +88 -0
  369. package/dist/worker/console/static/assets/chunk-GF5L2VYU-srJkaP3f.js +206 -0
  370. package/dist/worker/console/static/assets/chunk-JWPE2WC7-UYGvEP4l.js +1 -0
  371. package/dist/worker/console/static/assets/chunk-KBJHAD2P-B8luBrrz.js +1 -0
  372. package/dist/worker/console/static/assets/chunk-RYQCIY6F-DN7wXZSq.js +1 -0
  373. package/dist/worker/console/static/assets/chunk-XXDRQBXY-DXKyMuKS.js +1 -0
  374. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BaehtRk4.js +1 -0
  375. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BaehtRk4.js +1 -0
  376. package/dist/worker/console/static/assets/cose-bilkent-JH36ORCC-dqvoynXj.js +1 -0
  377. package/dist/worker/console/static/assets/cynefin-VYW2F7L2--PcyL34A.js +166 -0
  378. package/dist/worker/console/static/assets/cynefinDiagram-MW4NZA55-DvWs_hTY.js +62 -0
  379. package/dist/worker/console/static/assets/cytoscape.esm-yzknjiTM.js +321 -0
  380. package/dist/worker/console/static/assets/dagre-VZM6K2ZE-DxeIxbyO.js +4 -0
  381. package/dist/worker/console/static/assets/defaultLocale-DX6XiGOO.js +1 -0
  382. package/dist/worker/console/static/assets/diagram-7IWD3JNH-DPCG61Of.js +30 -0
  383. package/dist/worker/console/static/assets/diagram-B4RE2ZJO-CmuU50-U.js +3 -0
  384. package/dist/worker/console/static/assets/diagram-LBJQPF4R-B61XLD_v.js +24 -0
  385. package/dist/worker/console/static/assets/diagram-Q27KOJAE-BB7HTRRY.js +24 -0
  386. package/dist/worker/console/static/assets/diagram-UB23O5K3-DvkboAIp.js +41 -0
  387. package/dist/worker/console/static/assets/ebnfDiagram-BXEA7PRR-BdJ_y1fL.js +1 -0
  388. package/dist/worker/console/static/assets/erDiagram-JOGREHBK-9bUBZTRi.js +85 -0
  389. package/dist/worker/console/static/assets/flowDiagram-UKHOOZJN-Dw4L4RBa.js +156 -0
  390. package/dist/worker/console/static/assets/ganttDiagram-PKOTCBZU-Jr82N_QP.js +292 -0
  391. package/dist/worker/console/static/assets/gitGraphDiagram-DS77QQ5N-DAz9wFLr.js +106 -0
  392. package/dist/worker/console/static/assets/graph-DOmOIIwC.js +1 -0
  393. package/dist/worker/console/static/assets/index-B7Y-0g3J.css +1 -0
  394. package/dist/worker/console/static/assets/index-DkCrqaYg.js +325 -0
  395. package/dist/worker/console/static/assets/infoDiagram-6WML65LV-CBB5Np7y.js +2 -0
  396. package/dist/worker/console/static/assets/init-Gi6I4Gst.js +1 -0
  397. package/dist/worker/console/static/assets/ishikawaDiagram-WSZJBQD7-D8IOp94y.js +70 -0
  398. package/dist/worker/console/static/assets/journeyDiagram-NVQOT4AX-Dgd3AHGG.js +139 -0
  399. package/dist/worker/console/static/assets/kanban-definition-27J2QSJJ-BmYOxLE9.js +89 -0
  400. package/dist/worker/console/static/assets/layout-D-LzfAck.js +1 -0
  401. package/dist/worker/console/static/assets/linear-DfYTEF6J.js +1 -0
  402. package/dist/worker/console/static/assets/map-DxJ2ADlA.js +1 -0
  403. package/dist/worker/console/static/assets/mermaid.core-BjuFPRqa.js +308 -0
  404. package/dist/worker/console/static/assets/mindmap-definition-FAOFIHXS-CLyUViGd.js +96 -0
  405. package/dist/worker/console/static/assets/ordinal-Cboi1Yqb.js +1 -0
  406. package/dist/worker/console/static/assets/pegDiagram-VL7TDLO6-BvX2Di4-.js +1 -0
  407. package/dist/worker/console/static/assets/pieDiagram-7S7Q4E2Y-BFj0_OLv.js +39 -0
  408. package/dist/worker/console/static/assets/quadrantDiagram-CIZ2JOQS-BIUrD_hx.js +7 -0
  409. package/dist/worker/console/static/assets/railroadDiagram-AXF67PYL-CHBB48fj.js +1 -0
  410. package/dist/worker/console/static/assets/requirementDiagram-LRYGKXZP-sJrYw2Sf.js +84 -0
  411. package/dist/worker/console/static/assets/sankeyDiagram-W5VNT64P-BzHH6fPR.js +40 -0
  412. package/dist/worker/console/static/assets/sequenceDiagram-SI44F4Z6-7QCnelCt.js +162 -0
  413. package/dist/worker/console/static/assets/sizeCapture-X5ZJPWSS-sDYSxn72.js +1 -0
  414. package/dist/worker/console/static/assets/stateDiagram-OKZ733FA-XpiUdwzm.js +1 -0
  415. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-eEhq2A8Y.js +1 -0
  416. package/dist/worker/console/static/assets/swimlanes-SLNWSIFB-DvqgNPzD.js +2 -0
  417. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-la8AC7fo.js +8 -0
  418. package/dist/worker/console/static/assets/timeline-definition-Z64GVDOM-2TyOYNx0.js +120 -0
  419. package/dist/worker/console/static/assets/vennDiagram-T6HMQDX7-B-nM6wM2.js +34 -0
  420. package/dist/worker/console/static/assets/wardleyDiagram-T6FBY63Y-B86wPdbr.js +78 -0
  421. package/dist/worker/console/static/assets/xychartDiagram-ELKLHX3M-Dr1C4AQz.js +7 -0
  422. package/dist/worker/console/static/favicon.svg +37 -0
  423. package/dist/worker/console/static/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
  424. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
  425. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
  426. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
  427. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
  428. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
  429. package/dist/worker/console/static/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
  430. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
  431. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
  432. package/dist/worker/console/static/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
  433. package/dist/worker/console/static/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
  434. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
  435. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
  436. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
  437. package/dist/worker/console/static/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
  438. package/dist/worker/console/static/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
  439. package/dist/worker/console/static/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
  440. package/dist/worker/console/static/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
  441. package/dist/worker/console/static/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
  442. package/dist/worker/console/static/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
  443. package/dist/worker/console/static/index.html +15 -0
  444. package/dist/worker/console/static-src/app/console-types.js +184 -0
  445. package/dist/worker/console/static-src/app/useConsoleShell.js +101 -0
  446. package/dist/worker/console/static-src/app/useOperatorActions.js +324 -0
  447. package/dist/worker/console/static-src/app/usePrdImport.js +172 -0
  448. package/dist/worker/console/static-src/app/useRecoveryActions.js +289 -0
  449. package/dist/worker/console/static-src/app/useRecoveryConsole.js +425 -0
  450. package/dist/worker/console/static-src/app/useTaskWizard.js +296 -0
  451. package/dist/worker/console/static-src/chat-markdown-security.js +38 -0
  452. package/dist/worker/console/static-src/chat-view-types.js +2 -0
  453. package/dist/worker/console/static-src/night/night-types.js +24 -0
  454. package/dist/worker/console/static-src/night/useNightBoard.js +94 -0
  455. package/dist/worker/console/static-src/night/useNightWizard.js +171 -0
  456. package/dist/worker/console/static-src/night-prepare-result.js +118 -0
  457. package/dist/worker/console/static-src/operator-chat/activity-journey.js +125 -0
  458. package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +73 -0
  459. package/dist/worker/console/static-src/operator-chat/activity-references.js +20 -0
  460. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +420 -0
  461. package/dist/worker/console/static-src/operator-chat/format.js +71 -0
  462. package/dist/worker/console/static-src/operator-chat/landing-density.js +23 -0
  463. package/dist/worker/console/static-src/operator-chat/mutation-gate.js +45 -0
  464. package/dist/worker/console/static-src/operator-chat/refs.js +86 -0
  465. package/dist/worker/console/static-src/operator-chat/resource-auto-invocation.js +91 -0
  466. package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
  467. package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +257 -0
  468. package/dist/worker/console/static-src/operator-chat/session-title-watcher.js +128 -0
  469. package/dist/worker/console/static-src/operator-chat/sidebar-split.js +90 -0
  470. package/dist/worker/console/static-src/operator-chat/slash-palette-layout.js +24 -0
  471. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +141 -0
  472. package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +38 -0
  473. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +77 -0
  474. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +690 -0
  475. package/dist/worker/console/static-src/operator-chat/turn-submission.js +158 -0
  476. package/dist/worker/console/static-src/operator-chat/types.js +1 -0
  477. package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +59 -0
  478. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +495 -0
  479. package/dist/worker/console/static-src/operator-chat/useChatStream.js +780 -0
  480. package/dist/worker/console/static-src/operator-chat/useChatThread.js +280 -0
  481. package/dist/worker/console/static-src/operator-chat/useComposer.js +257 -0
  482. package/dist/worker/console/static-src/operator-chat/useInterview.js +108 -0
  483. package/dist/worker/console/static-src/operator-chat/useOverlayFocus.js +84 -0
  484. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +148 -0
  485. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +358 -0
  486. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +196 -0
  487. package/dist/worker/console/static-src/operator-chat/useWorkspaceLayout.js +58 -0
  488. package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +35 -0
  489. package/dist/worker/console/static-src/prd-file-import.js +218 -0
  490. package/dist/worker/console/vite.config.js +27 -0
  491. package/dist/worker/console/workflow-kinds.js +46 -0
  492. package/dist/worker/delivery/final-verification.js +302 -0
  493. package/dist/worker/delivery/git-transaction.js +497 -0
  494. package/dist/worker/delivery/package.js +537 -0
  495. package/dist/worker/delivery/verification-bundle.js +544 -0
  496. package/dist/worker/feature/acceptance-policy.js +227 -0
  497. package/dist/worker/feature/advance.js +301 -0
  498. package/dist/worker/feature/decision-loader.js +99 -0
  499. package/dist/worker/feature/discover.js +14 -0
  500. package/dist/worker/feature/doctor.js +223 -0
  501. package/dist/worker/feature/fullstack-validate.js +337 -0
  502. package/dist/worker/feature/next-action.js +140 -0
  503. package/dist/worker/feature/profile-schema.js +47 -0
  504. package/dist/worker/feature/ready-plan-projection.js +82 -0
  505. package/dist/worker/feature/reducer.js +137 -0
  506. package/dist/worker/feature/review.js +678 -0
  507. package/dist/worker/feature/run.js +390 -0
  508. package/dist/worker/feature/scaffold.js +812 -0
  509. package/dist/worker/feature/types.js +1 -0
  510. package/dist/worker/follow-up/approve.js +273 -0
  511. package/dist/worker/follow-up/factory.js +234 -0
  512. package/dist/worker/follow-up/paths.js +25 -0
  513. package/dist/worker/follow-up/policy.js +26 -0
  514. package/dist/worker/follow-up/schema.js +93 -0
  515. package/dist/worker/follow-up/store.js +96 -0
  516. package/dist/worker/loop-agent/command-result.js +1 -0
  517. package/dist/worker/loop-agent/controller-protocol.js +143 -0
  518. package/dist/worker/loop-agent/loop-agent-client.js +489 -0
  519. package/dist/worker/loop-agent/parse-json.js +14 -0
  520. package/dist/worker/materialize/harness-task-lifecycle-probe.js +126 -0
  521. package/dist/worker/materialize/harness-task-lineage.js +220 -0
  522. package/dist/worker/materialize/harness-task-materializer.js +648 -0
  523. package/dist/worker/metrics/projector.js +139 -0
  524. package/dist/worker/observability/dag-execution-trajectory.js +591 -0
  525. package/dist/worker/observability/event-history.js +216 -0
  526. package/dist/worker/observability/event-store.js +83 -0
  527. package/dist/worker/observability/events.js +79 -0
  528. package/dist/worker/observability/interrupt-eligibility.js +264 -0
  529. package/dist/worker/observability/progress-composite.js +34 -0
  530. package/dist/worker/observability/read-model.js +2499 -0
  531. package/dist/worker/observability/snapshot-store.js +43 -0
  532. package/dist/worker/observability/types.js +1 -0
  533. package/dist/worker/observe/dag-node-execution-output.js +180 -0
  534. package/dist/worker/observe/dag-run-artifacts.js +90 -0
  535. package/dist/worker/observe/health.js +58 -0
  536. package/dist/worker/observe/night-jobs.js +104 -0
  537. package/dist/worker/observe/node-input.js +441 -0
  538. package/dist/worker/observe/paths.js +174 -0
  539. package/dist/worker/observe/routes.js +1077 -0
  540. package/dist/worker/observe/server.js +117 -0
  541. package/dist/worker/observe/spec-evidence.js +398 -0
  542. package/dist/worker/observe/static/api.js +117 -0
  543. package/dist/worker/observe/static/app.js +169 -0
  544. package/dist/worker/observe/static/constants.js +182 -0
  545. package/dist/worker/observe/static/copy.js +67 -0
  546. package/dist/worker/observe/static/custom-select.js +567 -0
  547. package/dist/worker/observe/static/dag-edge-routing.js +368 -0
  548. package/dist/worker/observe/static/dag-helpers.js +161 -0
  549. package/dist/worker/observe/static/dag-history-labels.js +95 -0
  550. package/dist/worker/observe/static/dag-layout.d.ts +36 -0
  551. package/dist/worker/observe/static/dag-layout.js +163 -0
  552. package/dist/worker/observe/static/dag-model.js +145 -0
  553. package/dist/worker/observe/static/dom.js +220 -0
  554. package/dist/worker/observe/static/favicon.svg +37 -0
  555. package/dist/worker/observe/static/format-pool.d.ts +71 -0
  556. package/dist/worker/observe/static/format-pool.js +153 -0
  557. package/dist/worker/observe/static/format.js +347 -0
  558. package/dist/worker/observe/static/index.html +409 -0
  559. package/dist/worker/observe/static/kpi.js +78 -0
  560. package/dist/worker/observe/static/markdown-render.js +124 -0
  561. package/dist/worker/observe/static/operator-chrome.css +517 -0
  562. package/dist/worker/observe/static/operator-chrome.d.ts +83 -0
  563. package/dist/worker/observe/static/operator-chrome.js +623 -0
  564. package/dist/worker/observe/static/relations.js +133 -0
  565. package/dist/worker/observe/static/router.js +156 -0
  566. package/dist/worker/observe/static/run-processing.js +148 -0
  567. package/dist/worker/observe/static/shell-chrome.js +65 -0
  568. package/dist/worker/observe/static/state.js +496 -0
  569. package/dist/worker/observe/static/styles.css +3567 -0
  570. package/dist/worker/observe/static/views/batch.js +227 -0
  571. package/dist/worker/observe/static/views/dag-graph.js +508 -0
  572. package/dist/worker/observe/static/views/dag-inspector.js +1722 -0
  573. package/dist/worker/observe/static/views/dag-trajectory.js +313 -0
  574. package/dist/worker/observe/static/views/dag.js +483 -0
  575. package/dist/worker/observe/static/views/dags.js +877 -0
  576. package/dist/worker/observe/static/views/dashboard.js +747 -0
  577. package/dist/worker/observe/static/views/failures.js +143 -0
  578. package/dist/worker/observe/static/views/feature.js +492 -0
  579. package/dist/worker/observe/static/views/night.js +201 -0
  580. package/dist/worker/observe/static/views/pool.js +708 -0
  581. package/dist/worker/observe/static/views/run.js +453 -0
  582. package/dist/worker/observe/static/views/session-timeline.js +771 -0
  583. package/dist/worker/observe/static/views/shell.js +7 -0
  584. package/dist/worker/observe/static/views/task.js +315 -0
  585. package/dist/worker/observe/static/views/timeline.js +163 -0
  586. package/dist/worker/outcomes/adapters.js +153 -0
  587. package/dist/worker/outcomes/declared-artifacts.js +103 -0
  588. package/dist/worker/outcomes/evidence-tokens.js +29 -0
  589. package/dist/worker/outcomes/gate.js +40 -0
  590. package/dist/worker/outcomes/projector.js +227 -0
  591. package/dist/worker/outcomes/registry.js +1 -0
  592. package/dist/worker/outcomes/store.js +131 -0
  593. package/dist/worker/outcomes/types.js +79 -0
  594. package/dist/worker/pool/attempt-identity.js +41 -0
  595. package/dist/worker/pool/attempt-lease.js +184 -0
  596. package/dist/worker/pool/attempt-transition.js +210 -0
  597. package/dist/worker/pool/begin-attempt-with-lease.js +26 -0
  598. package/dist/worker/pool/begin-attempt.js +35 -0
  599. package/dist/worker/pool/doctor.js +165 -0
  600. package/dist/worker/pool/failure-routing.js +182 -0
  601. package/dist/worker/pool/migrate-state.js +303 -0
  602. package/dist/worker/pool/reconcile.js +285 -0
  603. package/dist/worker/pool/recovery-decision.js +163 -0
  604. package/dist/worker/pool/run-owner-store.js +126 -0
  605. package/dist/worker/pool/run-store.js +360 -0
  606. package/dist/worker/pool/runtime-reconcile-inventory.js +127 -0
  607. package/dist/worker/pool/state-projection.js +57 -0
  608. package/dist/worker/pool/types.js +17 -0
  609. package/dist/worker/pool/validation.js +144 -0
  610. package/dist/worker/preflight.js +157 -0
  611. package/dist/worker/profile-mapping.js +76 -0
  612. package/dist/worker/progress-reporter.js +63 -0
  613. package/dist/worker/report/morning-report.js +155 -0
  614. package/dist/worker/repos/repo-resolver.js +23 -0
  615. package/dist/worker/run-task/execute-prepared-task.js +178 -0
  616. package/dist/worker/run-task/run-task.js +912 -0
  617. package/dist/worker/runner/run-ready.js +561 -0
  618. package/dist/worker/runner/single-task-attempt.js +176 -0
  619. package/dist/worker/scheduler/admission.js +547 -0
  620. package/dist/worker/scheduler/auto-followup.js +99 -0
  621. package/dist/worker/scheduler/cli.js +644 -0
  622. package/dist/worker/scheduler/clock-install/darwin-launchd.js +238 -0
  623. package/dist/worker/scheduler/clock-install/linux-systemd-user.js +224 -0
  624. package/dist/worker/scheduler/clock-install/types.js +1 -0
  625. package/dist/worker/scheduler/clock-install/win32-schtasks.js +227 -0
  626. package/dist/worker/scheduler/clock-install.js +284 -0
  627. package/dist/worker/scheduler/clock.js +420 -0
  628. package/dist/worker/scheduler/dispatcher.js +503 -0
  629. package/dist/worker/scheduler/doctor.js +431 -0
  630. package/dist/worker/scheduler/evidence.js +170 -0
  631. package/dist/worker/scheduler/git-base.js +90 -0
  632. package/dist/worker/scheduler/index.js +25 -0
  633. package/dist/worker/scheduler/lease.js +114 -0
  634. package/dist/worker/scheduler/lifecycle.js +348 -0
  635. package/dist/worker/scheduler/lock.js +80 -0
  636. package/dist/worker/scheduler/morning-window.js +191 -0
  637. package/dist/worker/scheduler/night-git-finalizer.js +114 -0
  638. package/dist/worker/scheduler/night-harvest.js +412 -0
  639. package/dist/worker/scheduler/paths.js +92 -0
  640. package/dist/worker/scheduler/prepared-attempt-recovery.js +471 -0
  641. package/dist/worker/scheduler/recovery.js +277 -0
  642. package/dist/worker/scheduler/reservation.js +146 -0
  643. package/dist/worker/scheduler/retry.js +199 -0
  644. package/dist/worker/scheduler/scheduler-loop.js +272 -0
  645. package/dist/worker/scheduler/store.js +275 -0
  646. package/dist/worker/scheduler/traceability.js +54 -0
  647. package/dist/worker/scheduler/trigger.js +258 -0
  648. package/dist/worker/scheduler/types.js +369 -0
  649. package/dist/worker/scheduler/workspace-adapter.js +128 -0
  650. package/dist/worker/task-graph/acceptance-schema.js +40 -0
  651. package/dist/worker/task-graph/ready-planner.js +267 -0
  652. package/dist/worker/task-graph/ready-queue.js +23 -0
  653. package/dist/worker/task-graph/task-graph-schema.js +59 -0
  654. package/dist/worker/task-graph/types.js +1 -0
  655. package/dist/worker/task-graph/validate.js +293 -0
  656. package/dist/worker/task-spec/complexity-mapping.js +8 -0
  657. package/dist/worker/task-spec/schema.js +125 -0
  658. package/dist/worker/task-spec/types.js +1 -0
  659. package/dist/worker/task-spec/validate.js +391 -0
  660. package/dist/worker/task-spec/workflow-routing.js +149 -0
  661. package/dist/workflows/dag/authoring.js +8 -0
  662. package/dist/workflows/dag/authority-surface.js +138 -0
  663. package/dist/workflows/dag/backend-test-analysis-contract.js +507 -0
  664. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +1985 -0
  665. package/dist/workflows/dag/backend-test-case-manifest.js +638 -0
  666. package/dist/workflows/dag/backend-test-classification-contract.js +38 -0
  667. package/dist/workflows/dag/backend-test-contract-envelope.js +205 -0
  668. package/dist/workflows/dag/backend-test-coverage-contract.js +202 -0
  669. package/dist/workflows/dag/backend-test-execution-contract.js +715 -0
  670. package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
  671. package/dist/workflows/dag/backend-test-intake-context.js +178 -0
  672. package/dist/workflows/dag/backend-test-layout.js +133 -0
  673. package/dist/workflows/dag/backend-test-markdown-workflow.js +1984 -0
  674. package/dist/workflows/dag/backend-test-module-stem.js +26 -0
  675. package/dist/workflows/dag/backend-test-pytest-collection.js +859 -0
  676. package/dist/workflows/dag/backend-test-result-contract.js +1030 -0
  677. package/dist/workflows/dag/backend-test-scenario-param.js +1670 -0
  678. package/dist/workflows/dag/backend-test-scenario-partitions.js +249 -0
  679. package/dist/workflows/dag/backend-test-semantic-review-contract.js +36 -0
  680. package/dist/workflows/dag/backend-test-stability-contract.js +57 -0
  681. package/dist/workflows/dag/backend-test-writer-completeness.js +1058 -0
  682. package/dist/workflows/dag/budget-enforcement.js +67 -0
  683. package/dist/workflows/dag/canvas-observer.js +474 -0
  684. package/dist/workflows/dag/context-policy.js +137 -0
  685. package/dist/workflows/dag/contract-output-registry.js +14 -0
  686. package/dist/workflows/dag/contract-validator-registrations.js +10 -0
  687. package/dist/workflows/dag/controller-identity.js +104 -0
  688. package/dist/workflows/dag/convergence/controller.js +596 -0
  689. package/dist/workflows/dag/decision-envelope.js +557 -0
  690. package/dist/workflows/dag/decision-evidence.js +153 -0
  691. package/dist/workflows/dag/decision-gates.js +1 -0
  692. package/dist/workflows/dag/dynamic-runtime/condition.js +48 -0
  693. package/dist/workflows/dag/dynamic-runtime/loop-until.js +161 -0
  694. package/dist/workflows/dag/dynamic-runtime/map.js +435 -0
  695. package/dist/workflows/dag/dynamic-runtime/reduction.js +72 -0
  696. package/dist/workflows/dag/dynamic-runtime/shared.js +203 -0
  697. package/dist/workflows/dag/event-observer.js +132 -0
  698. package/dist/workflows/dag/executor-registry.js +23 -0
  699. package/dist/workflows/dag/facts.js +4 -0
  700. package/dist/workflows/dag/failure-category.js +118 -0
  701. package/dist/workflows/dag/failure-routing.js +105 -0
  702. package/dist/workflows/dag/final-verification.js +180 -0
  703. package/dist/workflows/dag/frontend-implementation-contract.js +1911 -0
  704. package/dist/workflows/dag/frontend-lint-baseline.js +474 -0
  705. package/dist/workflows/dag/frontend-plan-render.js +90 -0
  706. package/dist/workflows/dag/frontend-prewrite-gate.js +1011 -0
  707. package/dist/workflows/dag/frontend-project-capability.js +1 -0
  708. package/dist/workflows/dag/frontend-recovery-plan.js +73 -0
  709. package/dist/workflows/dag/frontend-recovery-root-manifest.js +123 -0
  710. package/dist/workflows/dag/frontend-recovery-run.js +539 -0
  711. package/dist/workflows/dag/frontend-repair.js +541 -0
  712. package/dist/workflows/dag/frontend-review-context.js +116 -0
  713. package/dist/workflows/dag/frontend-risk.js +161 -0
  714. package/dist/workflows/dag/frontend-test-case-checklist.js +343 -0
  715. package/dist/workflows/dag/frontend-test-case-manifest.js +104 -0
  716. package/dist/workflows/dag/frontend-test-case-quality.js +105 -0
  717. package/dist/workflows/dag/frontend-test-html-report.js +174 -0
  718. package/dist/workflows/dag/frontend-test-l5-report.js +177 -0
  719. package/dist/workflows/dag/frontend-test-result-contract.js +487 -0
  720. package/dist/workflows/dag/frontend-verification-trace.js +275 -0
  721. package/dist/workflows/dag/frontend-worktree-diff.js +201 -0
  722. package/dist/workflows/dag/frontend-writer-recovery.js +106 -0
  723. package/dist/workflows/dag/frontend-writer-rollback.js +821 -0
  724. package/dist/workflows/dag/governance-constants.js +5 -0
  725. package/dist/workflows/dag/governance-profile.js +413 -0
  726. package/dist/workflows/dag/index.js +6 -0
  727. package/dist/workflows/dag/init-hybrid.js +7345 -0
  728. package/dist/workflows/dag/interrupt-request.js +559 -0
  729. package/dist/workflows/dag/knowledge-curator.js +165 -0
  730. package/dist/workflows/dag/l5-report-metrics.js +33 -0
  731. package/dist/workflows/dag/lifecycle.js +855 -0
  732. package/dist/workflows/dag/liveness-policy.js +251 -0
  733. package/dist/workflows/dag/node-execution.js +1081 -0
  734. package/dist/workflows/dag/observer-compose.js +52 -0
  735. package/dist/workflows/dag/output-protocol.js +356 -0
  736. package/dist/workflows/dag/project-governance-context.js +514 -0
  737. package/dist/workflows/dag/prompt-source.js +88 -0
  738. package/dist/workflows/dag/prompt.js +348 -0
  739. package/dist/workflows/dag/reconcile-run.js +145 -0
  740. package/dist/workflows/dag/reconcile-tasks.js +404 -0
  741. package/dist/workflows/dag/recovery-recommendation.js +329 -0
  742. package/dist/workflows/dag/repair-artifact.js +363 -0
  743. package/dist/workflows/dag/report.js +1229 -0
  744. package/dist/workflows/dag/rerun-plan.js +614 -0
  745. package/dist/workflows/dag/rerun-run.js +556 -0
  746. package/dist/workflows/dag/rerun-task.js +370 -0
  747. package/dist/workflows/dag/retry-policy.js +263 -0
  748. package/dist/workflows/dag/run-store.js +41 -0
  749. package/dist/workflows/dag/runner.js +1069 -0
  750. package/dist/workflows/dag/runtime-contract.js +87 -0
  751. package/dist/workflows/dag/runtime.js +5 -0
  752. package/dist/workflows/dag/scheduler.js +497 -0
  753. package/dist/workflows/dag/sdd-embedded.js +128 -0
  754. package/dist/workflows/dag/skill-instructions.js +478 -0
  755. package/dist/workflows/dag/skill-snapshot.js +553 -0
  756. package/dist/workflows/dag/skills.js +41 -0
  757. package/dist/workflows/dag/spec.js +3 -0
  758. package/dist/workflows/dag/task-contract-binding.js +138 -0
  759. package/dist/workflows/dag/task-demand-routing.js +1 -0
  760. package/dist/workflows/dag/topo.js +30 -0
  761. package/dist/workflows/dag/types.js +1145 -0
  762. package/dist/workflows/dag/upstream-artifacts.js +98 -0
  763. package/dist/workflows/dag/validate.js +998 -0
  764. package/dist/workflows/dag/workspace-checkpoint.js +186 -0
  765. package/dist/workflows/dynamic/artifacts.js +65 -0
  766. package/dist/workflows/dynamic/compile.js +371 -0
  767. package/dist/workflows/dynamic/compileTypes.js +1 -0
  768. package/dist/workflows/dynamic/errors.js +5 -0
  769. package/dist/workflows/dynamic/index.js +7 -0
  770. package/dist/workflows/dynamic/profiles.js +156 -0
  771. package/dist/workflows/dynamic/spec.js +115 -0
  772. package/dist/workflows/dynamic/validate.js +275 -0
  773. package/dist/workflows/loop/actions/dag-action.js +129 -0
  774. package/dist/workflows/loop/actions/pi-review.js +267 -0
  775. package/dist/workflows/loop/actions/shared.js +157 -0
  776. package/dist/workflows/loop/actions/shell-verify.js +82 -0
  777. package/dist/workflows/loop/actions/types.js +1 -0
  778. package/dist/workflows/loop/actions/workflow-action.js +255 -0
  779. package/dist/workflows/loop/actions.js +160 -0
  780. package/dist/workflows/loop/benchmark.js +510 -0
  781. package/dist/workflows/loop/closeout.js +135 -0
  782. package/dist/workflows/loop/context.js +47 -0
  783. package/dist/workflows/loop/events.js +26 -0
  784. package/dist/workflows/loop/hash.js +32 -0
  785. package/dist/workflows/loop/index.js +8 -0
  786. package/dist/workflows/loop/paths.js +17 -0
  787. package/dist/workflows/loop/policy/auto-policy.js +112 -0
  788. package/dist/workflows/loop/policy/path-patterns.js +13 -0
  789. package/dist/workflows/loop/rounds.js +81 -0
  790. package/dist/workflows/loop/signals.js +52 -0
  791. package/dist/workflows/loop/state.js +116 -0
  792. package/dist/workflows/loop/templates.js +54 -0
  793. package/dist/workflows/loop/types.js +28 -0
  794. package/docs/README.md +82 -0
  795. package/docs/architecture/README.md +35 -0
  796. package/docs/architecture/dag-execution.md +165 -0
  797. package/docs/architecture/evolution.md +108 -0
  798. package/docs/architecture/facts-and-state.md +74 -0
  799. package/docs/architecture/runtime-boundaries.md +226 -0
  800. package/docs/architecture/system-overview.md +100 -0
  801. package/docs/architecture/worker-and-feature.md +122 -0
  802. package/docs/governance/README.md +18 -0
  803. package/docs/governance/harness-methodology-debugging.md +177 -0
  804. package/docs/governance/harness-methodology-tdd.md +130 -0
  805. package/docs/governance/harness-methodology-verification.md +27 -0
  806. package/docs/init-surface.manifest.json +358 -0
  807. package/docs/operations/README.md +15 -0
  808. package/docs/operations/local-development-environment.md +77 -0
  809. package/docs/skills/README.md +7 -0
  810. package/docs/skills/vetted-skill-registry.md +49 -0
  811. package/docs/templates/README.md +67 -0
  812. package/docs/templates/adr.md +60 -0
  813. package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -0
  814. package/docs/templates/agent-dag-decision-envelope.schema.json +213 -0
  815. package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -0
  816. package/docs/templates/agent-dag-decision-gate.prompt.md +246 -0
  817. package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -0
  818. package/docs/templates/agent-dag-report.schema.json +473 -0
  819. package/docs/templates/agent-dag-review-verdict.prompt.md +68 -0
  820. package/docs/templates/agent-dag.base.json +190 -0
  821. package/docs/templates/agent-dag.final-verification.json +185 -0
  822. package/docs/templates/agent-dag.schema.json +590 -0
  823. package/docs/templates/agent-dag.supervised-implementation.json +640 -0
  824. package/docs/templates/agent-worker-production-readiness-checklist.md +47 -0
  825. package/docs/templates/backend-test-analysis.schema.json +37 -0
  826. package/docs/templates/backend-test-case-manifest.schema.json +223 -0
  827. package/docs/templates/backend-test-dag.classify.prompt.md +75 -0
  828. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +41 -0
  829. package/docs/templates/backend-test-dag.json +671 -0
  830. package/docs/templates/backend-test-dag.retrospect.prompt.md +165 -0
  831. package/docs/templates/backend-test-dag.review-cases.prompt.md +36 -0
  832. package/docs/templates/backend-test-execution.schema.json +138 -0
  833. package/docs/templates/backend-test-result.schema.json +99 -0
  834. package/docs/templates/branch-merge-report.md +115 -0
  835. package/docs/templates/evaluation/agents-map-slim-v1.candidate.json +9 -0
  836. package/docs/templates/evaluation/agents-map-slim-v1.md +87 -0
  837. package/docs/templates/evaluation/agents-map-verbose-v0.candidate.json +9 -0
  838. package/docs/templates/evaluation/agents-map-verbose-v0.md +153 -0
  839. package/docs/templates/evaluation/campaign-budget-v1.json +12 -0
  840. package/docs/templates/evaluation/campaign-dogfood-v0.json +24 -0
  841. package/docs/templates/evaluation/campaign-evidence-v1.json +44 -0
  842. package/docs/templates/evaluation/context-policy-baseline-v1.json +17 -0
  843. package/docs/templates/evaluation/context-policy-role-specialized-v1.json +28 -0
  844. package/docs/templates/evaluation/corpus-dogfood-v0.manifest.json +118 -0
  845. package/docs/templates/evaluation/matrix-dag-dry-run-v1.json +21 -0
  846. package/docs/templates/evaluation/matrix-fixture-v1.json +10 -0
  847. package/docs/templates/evaluation/private-verifier-dogfood-v0.json +16 -0
  848. package/docs/templates/exec-plan.md +66 -0
  849. package/docs/templates/feature-spec.md +53 -0
  850. package/docs/templates/frontend-design-contract.md +68 -0
  851. package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -0
  852. package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -0
  853. package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -0
  854. package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -0
  855. package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -0
  856. package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -0
  857. package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -0
  858. package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -0
  859. package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -0
  860. package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -0
  861. package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -0
  862. package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -0
  863. package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -0
  864. package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -0
  865. package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -0
  866. package/docs/templates/frontend-eval/metrics.md +138 -0
  867. package/docs/templates/frontend-eval/smoke-targets.md +53 -0
  868. package/docs/templates/frontend-implementation-contract.schema.json +35 -0
  869. package/docs/templates/frontend-task-constraints.md +62 -0
  870. package/docs/templates/frontend-task-requirement.md +104 -0
  871. package/docs/templates/frontend-test-case-checklist.md +44 -0
  872. package/docs/templates/frontend-test-case.example.md +143 -0
  873. package/docs/templates/frontend-test-dag.generate-cases.prompt.md +63 -0
  874. package/docs/templates/frontend-test-dag.json +409 -0
  875. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +21 -0
  876. package/docs/templates/frontend-test-dag.retrospect.prompt.md +5 -0
  877. package/docs/templates/frontend-test-dag.review-cases.prompt.md +5 -0
  878. package/docs/templates/frontend-test-dag.review-execution.prompt.md +3 -0
  879. package/docs/templates/frontend-test-standard-scenarios.v1.json +159 -0
  880. package/docs/templates/harness.schema.json +351 -0
  881. package/docs/templates/hybrid-dag.json +188 -0
  882. package/docs/templates/init-evolution-review.md +35 -0
  883. package/docs/templates/init-managed-agents.md +157 -0
  884. package/docs/templates/interactive-ui-round2-experiment.md +66 -0
  885. package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -0
  886. package/docs/templates/knowledge-sync-dag.json +178 -0
  887. package/docs/templates/knowledge-sync-draft.schema.json +71 -0
  888. package/docs/templates/product-line/AGENTS.md +9 -0
  889. package/docs/templates/product-line/README.md +42 -0
  890. package/docs/templates/product-line/acceptance.yaml +23 -0
  891. package/docs/templates/product-line/closeout.yaml +9 -0
  892. package/docs/templates/product-line/design.md +13 -0
  893. package/docs/templates/product-line/feature-scaffold-batch.example.yaml +31 -0
  894. package/docs/templates/product-line/feature.yaml +11 -0
  895. package/docs/templates/product-line/links.md +10 -0
  896. package/docs/templates/product-line/requirement.md +17 -0
  897. package/docs/templates/product-line/scaffold-samples/README.md +36 -0
  898. package/docs/templates/product-line/scaffold-samples/backend-only/acceptance.yaml +16 -0
  899. package/docs/templates/product-line/scaffold-samples/backend-only/design.md +14 -0
  900. package/docs/templates/product-line/scaffold-samples/backend-only/feature.yaml +14 -0
  901. package/docs/templates/product-line/scaffold-samples/backend-only/requirement.md +6 -0
  902. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/BE-IMPL-001.yaml +83 -0
  903. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/task-graph.yaml +14 -0
  904. package/docs/templates/product-line/scaffold-samples/fe-with-api/acceptance.yaml +18 -0
  905. package/docs/templates/product-line/scaffold-samples/fe-with-api/design.md +18 -0
  906. package/docs/templates/product-line/scaffold-samples/fe-with-api/feature.yaml +14 -0
  907. package/docs/templates/product-line/scaffold-samples/fe-with-api/requirement.md +6 -0
  908. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/BE-IMPL-001.yaml +84 -0
  909. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/CONTRACT-001.yaml +84 -0
  910. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/FE-IMPL-001.yaml +86 -0
  911. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/task-graph.yaml +40 -0
  912. package/docs/templates/product-line/scaffold-samples/frontend-only/acceptance.yaml +16 -0
  913. package/docs/templates/product-line/scaffold-samples/frontend-only/design.md +14 -0
  914. package/docs/templates/product-line/scaffold-samples/frontend-only/feature.yaml +14 -0
  915. package/docs/templates/product-line/scaffold-samples/frontend-only/requirement.md +6 -0
  916. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/FE-IMPL-001.yaml +85 -0
  917. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/task-graph.yaml +14 -0
  918. package/docs/templates/product-line/task-graph.yaml +23 -0
  919. package/docs/templates/product-line/task.yaml +68 -0
  920. package/docs/templates/product-line/test-plan.md +7 -0
  921. package/docs/templates/production-readiness-checklist.md +57 -0
  922. package/docs/templates/progress-log.md +27 -0
  923. package/docs/templates/project-start-checklist.md +9 -0
  924. package/docs/templates/qa-report.md +48 -0
  925. package/docs/templates/sprint-contract.md +29 -0
  926. package/docs/templates/worker-dogfood-evidence.md +80 -0
  927. package/docs/templates/worker-dogfood-setup.md +68 -0
  928. package/examples/decision-gate-agent-dag.json +177 -0
  929. package/examples/example-dag.json +46 -0
  930. package/examples/hybrid-loop-agent-dag.json +189 -0
  931. package/examples/l5-report-coms-process-definition.html +322 -0
  932. package/examples/l5-report-demo.html +79 -0
  933. package/harness.json +90 -0
  934. package/package.json +98 -0
  935. package/scripts/kb-bootstrap-init-skeleton.sh +241 -0
  936. package/scripts/kb-graph-incremental-prepare.mjs +386 -0
  937. package/scripts/kb-graph-materialize.mjs +105 -0
  938. package/scripts/kb-graph-promote.mjs +164 -0
  939. package/scripts/kb-query.mjs +554 -0
  940. package/skills/agent-worker/SKILL.md +48 -0
  941. package/skills/agent-worker/references/agent-worker-operator.md +159 -0
  942. package/skills/ai-engineering-context/SKILL.md +48 -0
  943. package/skills/analyze-product-dependencies/SKILL.md +108 -0
  944. package/skills/analyze-product-dependencies/references/api-documentation-schema.md +35 -0
  945. package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +38 -0
  946. package/skills/analyze-product-dependencies/references/example.md +76 -0
  947. package/skills/analyze-product-dependencies/references/forward-test-cases.md +110 -0
  948. package/skills/analyze-product-dependencies/references/input-contract.md +34 -0
  949. package/skills/analyze-product-dependencies/references/kb-integration.md +64 -0
  950. package/skills/analyze-product-dependencies/references/scouting-rules.md +76 -0
  951. package/skills/analyze-product-dependencies/scripts/test-validators.mjs +460 -0
  952. package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +194 -0
  953. package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +200 -0
  954. package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +90 -0
  955. package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +138 -0
  956. package/skills/analyze-product-requirements/SKILL.md +145 -0
  957. package/skills/analyze-product-requirements/references/acceptance-criteria.md +87 -0
  958. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +70 -0
  959. package/skills/analyze-product-requirements/references/example.md +104 -0
  960. package/skills/analyze-product-requirements/references/forward-test-cases.md +144 -0
  961. package/skills/analyze-product-requirements/references/kb-integration.md +56 -0
  962. package/skills/analyze-product-requirements/references/product-analysis-schema.md +41 -0
  963. package/skills/analyze-product-requirements/references/product-requirement-schema.md +42 -0
  964. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +66 -0
  965. package/skills/analyze-product-requirements/scripts/compute-source-identity.mjs +35 -0
  966. package/skills/analyze-product-requirements/scripts/test-validators.mjs +501 -0
  967. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +100 -0
  968. package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +109 -0
  969. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +109 -0
  970. package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +175 -0
  971. package/skills/browser-tools/SKILL.md +196 -0
  972. package/skills/browser-tools/browser-content.js +103 -0
  973. package/skills/browser-tools/browser-cookies.js +35 -0
  974. package/skills/browser-tools/browser-eval.js +53 -0
  975. package/skills/browser-tools/browser-hn-scraper.js +108 -0
  976. package/skills/browser-tools/browser-nav.js +44 -0
  977. package/skills/browser-tools/browser-pick.js +162 -0
  978. package/skills/browser-tools/browser-screenshot.js +34 -0
  979. package/skills/browser-tools/browser-start.js +86 -0
  980. package/skills/browser-tools/package-lock.json +2556 -0
  981. package/skills/browser-tools/package.json +19 -0
  982. package/skills/code-review-core/SKILL.md +20 -0
  983. package/skills/codebase-scout/SKILL.md +19 -0
  984. package/skills/frontend-bounded-implement/SKILL.md +53 -0
  985. package/skills/frontend-design-review/SKILL.md +79 -0
  986. package/skills/frontend-design-review/references/review-checklist.md +43 -0
  987. package/skills/frontend-implementation/SKILL.md +52 -0
  988. package/skills/frontend-implementation/references/code-standards.md +33 -0
  989. package/skills/frontend-implementation/references/design-spec.md +56 -0
  990. package/skills/frontend-implementation/references/node-contracts.md +31 -0
  991. package/skills/frontend-review/SKILL.md +55 -0
  992. package/skills/frontend-review/references/review-findings.md +50 -0
  993. package/skills/frontend-verification/SKILL.md +61 -0
  994. package/skills/frontend-verification/references/verification-checklist.md +48 -0
  995. package/skills/grill-me/SKILL.md +10 -0
  996. package/skills/grill-with-docs/SKILL.md +80 -0
  997. package/skills/grill-with-docs/adr-format.md +58 -0
  998. package/skills/grill-with-docs/context-format.md +52 -0
  999. package/skills/init-capability-evolution/SKILL.md +70 -0
  1000. package/skills/local-jacoco-coverage/SKILL.md +281 -0
  1001. package/skills/local-jacoco-coverage/references/requirement-to-source-mapping.md +85 -0
  1002. package/skills/local-jacoco-coverage/references/runtime-alignment.md +106 -0
  1003. package/skills/local-jacoco-coverage/scripts/run-coverage-analysis.sh +148 -0
  1004. package/skills/local-jacoco-coverage/scripts/start-jacoco-agent.sh +110 -0
  1005. package/skills/loop-agent/SKILL.md +68 -0
  1006. package/skills/loop-agent/references/README.md +67 -0
  1007. package/skills/loop-agent/references/command-reference.md +645 -0
  1008. package/skills/loop-agent/references/docs-converge.md +126 -0
  1009. package/skills/loop-agent/references/harness-policy.md +289 -0
  1010. package/skills/loop-agent/references/hybrid-dag.md +245 -0
  1011. package/skills/loop-agent/references/learned/README.md +21 -0
  1012. package/skills/loop-agent/references/long-running-loop.md +57 -0
  1013. package/skills/loop-agent/references/model-routing.md +45 -0
  1014. package/skills/loop-agent/references/multi-worktree.md +54 -0
  1015. package/skills/loop-agent/references/one-shot-runs.md +84 -0
  1016. package/skills/loop-agent/references/orchestrator-and-interventions.md +175 -0
  1017. package/skills/loop-agent/references/pi-prompt.md +23 -0
  1018. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -0
  1019. package/skills/loop-agent/references/post-implementation-and-patterns.md +54 -0
  1020. package/skills/loop-agent/references/source-and-plan-practice.md +169 -0
  1021. package/skills/loop-agent/references/task-workflow.md +104 -0
  1022. package/skills/loop-agent/references/verification-and-failure-handling.md +148 -0
  1023. package/skills/playwright-cli/SKILL.md +93 -0
  1024. package/skills/playwright-cli/references/element-attributes.md +23 -0
  1025. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  1026. package/skills/playwright-cli/references/request-mocking.md +87 -0
  1027. package/skills/playwright-cli/references/running-code.md +241 -0
  1028. package/skills/playwright-cli/references/session-management.md +225 -0
  1029. package/skills/playwright-cli/references/storage-state.md +275 -0
  1030. package/skills/playwright-cli/references/test-generation.md +433 -0
  1031. package/skills/playwright-cli/references/tracing.md +5 -0
  1032. package/skills/playwright-cli/references/video-recording.md +5 -0
  1033. package/skills/playwright-cli-case-generator/SKILL.md +108 -0
  1034. package/skills/requesting-code-review/SKILL.md +101 -0
  1035. package/skills/requesting-code-review/code-reviewer.md +168 -0
  1036. package/skills/systematic-debugging/CREATION-LOG.md +119 -0
  1037. package/skills/systematic-debugging/SKILL.md +312 -0
  1038. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  1039. package/skills/systematic-debugging/condition-based-waiting.md +115 -0
  1040. package/skills/systematic-debugging/defense-in-depth.md +122 -0
  1041. package/skills/systematic-debugging/find-polluter.sh +63 -0
  1042. package/skills/systematic-debugging/root-cause-tracing.md +169 -0
  1043. package/skills/systematic-debugging/test-academic.md +14 -0
  1044. package/skills/systematic-debugging/test-pressure-1.md +58 -0
  1045. package/skills/systematic-debugging/test-pressure-2.md +68 -0
  1046. package/skills/systematic-debugging/test-pressure-3.md +69 -0
  1047. package/skills/test-driven-development/SKILL.md +27 -0
  1048. package/skills/using-git-worktrees/SKILL.md +215 -0
  1049. package/skills/verification-before-completion/SKILL.md +154 -0
  1050. package/skills/webapp-testing/SKILL.md +19 -0
@@ -0,0 +1,1058 @@
1
+ import { createHash } from "node:crypto";
2
+ import { access, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { BACKEND_TEST_MAX_MODULE_COUNT, isOpaqueHashBackendTestModuleStem, isPriorityOnlyBackendTestModuleStem, } from "./backend-test-module-stem.js";
6
+ import { resolveBackendTestLayout, } from "./backend-test-layout.js";
7
+ /**
8
+ * Maps a backend-test generation writer task id to its writer-progress role.
9
+ * Returns undefined for nodes that are not completeness-gated generators.
10
+ *
11
+ * Recognizes both the legacy single-node literal ids
12
+ * (`generate-backend-md-cases-pi` / `generate-backend-pytest-pi`) and the
13
+ * map_agent sharded child ids (`generate-backend-md-case-0001` /
14
+ * `generate-backend-pytest-case-0001`). The literal fallback keeps hand-
15
+ * written test DAGs that bypass buildHybridDagFromTask green.
16
+ */
17
+ export function backendTestWriterProgressRoleForTask(taskId) {
18
+ if (!taskId)
19
+ return undefined;
20
+ if (taskId === "generate-backend-md-cases-pi" ||
21
+ taskId === "generate-backend-md-plan-pi" ||
22
+ taskId.startsWith("generate-backend-md-case-"))
23
+ return "md-generate";
24
+ if (taskId === "generate-backend-pytest-pi" ||
25
+ taskId === "generate-backend-pytest-plan-pi" ||
26
+ taskId.startsWith("generate-backend-pytest-case-"))
27
+ return "pytest-generate";
28
+ return undefined;
29
+ }
30
+ import { expectedBackendTestPytestScriptForMarkdownModule, normalizeBackendTestModuleStem, } from "./backend-test-markdown-workflow.js";
31
+ export const BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID = "backend-test-writer-progress-v1";
32
+ export const BACKEND_TEST_OUTPUT_LIMIT_RECOVERY_REPORT = "backend-test-output-limit-recovery.md";
33
+ const progressSchema = z
34
+ .object({
35
+ schemaId: z.literal(BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID),
36
+ role: z.enum(["md-generate", "pytest-generate", "report"]),
37
+ status: z.enum(["PASS", "RECOVERABLE", "NON_RECOVERABLE"]),
38
+ expectedPaths: z.array(z.string()),
39
+ actualPaths: z.array(z.string()),
40
+ missingPaths: z.array(z.string()),
41
+ brokenPaths: z.array(z.string()),
42
+ targetPaths: z.array(z.string()),
43
+ issues: z.array(z
44
+ .object({
45
+ code: z.enum(["T3", "T4", "T5", "T6"]),
46
+ path: z.string().optional(),
47
+ detail: z.string(),
48
+ recoverable: z.boolean(),
49
+ })
50
+ .strict()),
51
+ })
52
+ .strict();
53
+ async function exists(filePath) {
54
+ try {
55
+ await access(filePath);
56
+ return true;
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ function orderedUnique(values) {
63
+ return [...new Set(values.filter(Boolean))];
64
+ }
65
+ function hasMarkdownTable(section, headerNeedle) {
66
+ const lines = section
67
+ .replaceAll("\r\n", "\n")
68
+ .replaceAll("\r", "\n")
69
+ .split("\n");
70
+ // A markdown table header row must itself be a pipe-delimited row (start
71
+ // and end with `|`) AND be immediately followed by a separator row
72
+ // (`|---|`). Find the first row that satisfies both and contains the
73
+ // needle, so a Coverage Scope data cell like `| Affected Rule Keys |`
74
+ // (which mentions the needle but is not a header) does not shadow the
75
+ // real Coverage Matrix header further down.
76
+ const headerIndex = lines.findIndex((line, index) => {
77
+ const trimmed = line.trim();
78
+ const next = (lines[index + 1] ?? "").trim();
79
+ return (trimmed.startsWith("|") &&
80
+ trimmed.endsWith("|") &&
81
+ /^\|[-: |]+$/.test(next) &&
82
+ /-{3,}/.test(next) &&
83
+ line.toLowerCase().includes(headerNeedle.toLowerCase()));
84
+ });
85
+ if (headerIndex < 0)
86
+ return false;
87
+ const header = lines[headerIndex] ?? "";
88
+ const separator = lines[headerIndex + 1] ?? "";
89
+ return (header.includes("|") &&
90
+ /-{3,}/.test(separator) &&
91
+ separator.includes("|"));
92
+ }
93
+ /**
94
+ * A README module stem must be a stable lowercase business stem such as
95
+ * `health` or `resource_notes`. Reject tokens that are purely numeric, look
96
+ * like Case IDs, or were clearly lifted from prose examples (e.g. `1`,
97
+ * `9`, `BE-RN-001`). This prevents the completeness gate from inventing
98
+ * phantom missing modules when the model discusses forbidden filenames
99
+ * ("do not create 1.md / 9.md") inside the README body.
100
+ */
101
+ function moduleStemInvalidReason(raw) {
102
+ if (!raw)
103
+ return "invalid-syntax";
104
+ const stem = normalizeBackendTestModuleStem(raw);
105
+ if (isPriorityOnlyBackendTestModuleStem(stem))
106
+ return "priority-only-module-stem";
107
+ if (isOpaqueHashBackendTestModuleStem(stem))
108
+ return "opaque-hash-module-stem";
109
+ if (stem.toLowerCase() === "readme")
110
+ return "reserved-module-stem";
111
+ if (!/^[a-z][a-z0-9_]*$/.test(stem))
112
+ return "invalid-syntax";
113
+ if (/^(?:be|tp|ac|req|br)[_-]/i.test(stem))
114
+ return "case-like-module-stem";
115
+ return undefined;
116
+ }
117
+ function looksLikeValidModuleStem(raw) {
118
+ return moduleStemInvalidReason(raw) === undefined;
119
+ }
120
+ function extractCanonicalModuleIndexSection(readme) {
121
+ const lines = readme
122
+ .replaceAll("\r\n", "\n")
123
+ .replaceAll("\r", "\n")
124
+ .split("\n");
125
+ const headings = lines.flatMap((line, index) => line.trim() === "## Module Index" ? [index] : []);
126
+ if (headings.length === 0) {
127
+ return { section: "", structureIssues: ["missing-module-index"] };
128
+ }
129
+ if (headings.length > 1) {
130
+ return { section: "", structureIssues: ["duplicate-module-index"] };
131
+ }
132
+ const start = headings[0] + 1;
133
+ const relativeEnd = lines.slice(start).findIndex((line) => /^##\s+\S/.test(line.trim()));
134
+ const end = relativeEnd < 0 ? lines.length : start + relativeEnd;
135
+ return { section: lines.slice(start, end).join("\n"), structureIssues: [] };
136
+ }
137
+ /** Inspect only candidates inside the unique exact `## Module Index` section. */
138
+ export function inspectModuleStemsFromReadme(readme) {
139
+ const extracted = extractCanonicalModuleIndexSection(readme);
140
+ const candidates = [];
141
+ const tableRowLines = extracted.section.split("\n").filter((line) => line.includes("|"));
142
+ for (const line of tableRowLines) {
143
+ for (const match of line.matchAll(/`?testcase\/md\/([A-Za-z0-9_.-]+)\.md`?/g)) {
144
+ candidates.push(match[1]);
145
+ }
146
+ for (const match of line.matchAll(/\|\s*`?([A-Za-z0-9_.-]+)`?\s*\|\s*`?testcase\/test_/g)) {
147
+ const raw = match[1];
148
+ if (looksLikeValidModuleStem(raw) || moduleStemInvalidReason(raw) !== "invalid-syntax") {
149
+ candidates.push(raw);
150
+ }
151
+ }
152
+ }
153
+ for (const match of extracted.section.matchAll(/\[[^\]]+\]\(\.\/([A-Za-z0-9_.-]+)\.md\)/g)) {
154
+ candidates.push(match[1]);
155
+ }
156
+ const uniqueCandidates = orderedUnique(candidates);
157
+ const invalid = uniqueCandidates.flatMap((raw) => {
158
+ const reasonCode = moduleStemInvalidReason(raw);
159
+ return reasonCode
160
+ ? [{ raw, normalized: normalizeBackendTestModuleStem(raw), reasonCode }]
161
+ : [];
162
+ });
163
+ const validStems = orderedUnique(uniqueCandidates
164
+ .filter(looksLikeValidModuleStem)
165
+ .map((stem) => normalizeBackendTestModuleStem(stem)));
166
+ const structureIssues = [...extracted.structureIssues];
167
+ if (validStems.length > BACKEND_TEST_MAX_MODULE_COUNT) {
168
+ structureIssues.push(`excessive-module-count: ${validStems.length} > ${BACKEND_TEST_MAX_MODULE_COUNT}`);
169
+ }
170
+ return {
171
+ candidates: uniqueCandidates,
172
+ validStems,
173
+ invalid,
174
+ structureIssues,
175
+ };
176
+ }
177
+ /**
178
+ * Exported for reuse by callers that only need the trusted shard set.
179
+ * Completeness gates must use inspectModuleStemsFromReadme so invalid
180
+ * authoritative candidates cannot be silently dropped.
181
+ */
182
+ export function extractModuleStemsFromReadme(readme) {
183
+ return inspectModuleStemsFromReadme(readme).validStems;
184
+ }
185
+ async function listMarkdownModules(workspaceRoot, layout) {
186
+ const resolved = layout ?? resolveBackendTestLayout(undefined);
187
+ const root = path.join(workspaceRoot, ...resolved.markdownDir.split("/"));
188
+ if (!(await exists(root)))
189
+ return [];
190
+ const entries = await readdir(root, { withFileTypes: true });
191
+ return orderedUnique(entries
192
+ .filter((entry) => entry.isFile() &&
193
+ entry.name.toLowerCase().endsWith(".md") &&
194
+ entry.name.toLowerCase() !== "readme.md")
195
+ .map((entry) => path.posix.join(resolved.markdownDir, entry.name.replaceAll("\\", "/"))));
196
+ }
197
+ /**
198
+ * Recursively list `.py` file paths relative to `dirRoot` (forward slashes).
199
+ * Used by the pytest plan-node completeness check to discover shared
200
+ * helpers/factories resources.
201
+ */
202
+ async function listPythonFiles(dirRoot) {
203
+ if (!(await exists(dirRoot)))
204
+ return [];
205
+ const out = [];
206
+ const walk = async (rel) => {
207
+ const absolute = path.join(dirRoot, rel);
208
+ const entries = await readdir(absolute, { withFileTypes: true });
209
+ for (const entry of entries) {
210
+ const childRel = rel ? `${rel}/${entry.name}` : entry.name;
211
+ if (entry.isDirectory()) {
212
+ await walk(childRel);
213
+ }
214
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith(".py")) {
215
+ out.push(childRel.replaceAll("\\", "/"));
216
+ }
217
+ }
218
+ };
219
+ await walk("");
220
+ return orderedUnique(out);
221
+ }
222
+ const MODULE_REQUIRED_SECTIONS = [
223
+ "\u8986\u76d6\u89c4\u5219",
224
+ "\u6d4b\u8bd5\u70b9",
225
+ "\u573a\u666f\u7c7b\u578b",
226
+ "\u524d\u7f6e\u6761\u4ef6",
227
+ "\u64cd\u4f5c\u6b65\u9aa4",
228
+ "\u9884\u671f\u7ed3\u679c",
229
+ "\u81ea\u52a8\u5316\u6620\u5c04",
230
+ ];
231
+ /**
232
+ * Structural check for a backend-test Markdown module file. Returns structured
233
+ * reasons instead of a bare boolean so the Completeness Gate T5 detail and the
234
+ * retry prompt can tell the model exactly what is wrong (empty file / wrong
235
+ * case heading level / invalid case id format / missing sections). This avoids
236
+ * the "model cannot fix what it does not know" retry death-loop.
237
+ */
238
+ function moduleStructurallyComplete(markdown) {
239
+ if (!markdown.trim()) {
240
+ return { ok: false, reasons: ["file is empty"] };
241
+ }
242
+ const h2CaseMatch = /^##\s+BE-[A-Z0-9_-]+-\d{2,3}\b/m.exec(markdown);
243
+ if (!h2CaseMatch) {
244
+ // Distinguish "wrong level (### or ####)" from "invalid format / no case at all"
245
+ // so the retry hint is actionable.
246
+ const wrongLevel = /^#{3,4}\s+BE-[A-Z0-9_-]+-\d{2,3}\b/m.exec(markdown);
247
+ if (wrongLevel) {
248
+ const hashes = /^#+/.exec(wrongLevel[0])?.[0].length ?? 3;
249
+ return {
250
+ ok: false,
251
+ reasons: [
252
+ `case heading at wrong level: found '${hashes > 3 ? "####" : "###"} ${wrongLevel[0].replace(/^#+\s+/, "")}', require exactly 2 hashes '## BE-<MODULE>-<NNN>'`,
253
+ ],
254
+ };
255
+ }
256
+ const anyCaseId = /^#{2,4}\s+BE-[A-Z0-9_-]+-\d{1,4}/m.exec(markdown);
257
+ if (anyCaseId) {
258
+ return {
259
+ ok: false,
260
+ reasons: [
261
+ `invalid case heading format: '${anyCaseId[0].replace(/^#+\s+/, "")}' (need exactly 2-3 digit zero-padded NNN, e.g. BE-MOD-001)`,
262
+ ],
263
+ };
264
+ }
265
+ return {
266
+ ok: false,
267
+ reasons: [
268
+ "no h2 case heading found (require exactly '## BE-<MODULE>-<NNN>')",
269
+ ],
270
+ };
271
+ }
272
+ const missing = MODULE_REQUIRED_SECTIONS.filter((heading) => !markdown.includes(`### ${heading}`));
273
+ if (missing.length > 0) {
274
+ return {
275
+ ok: false,
276
+ reasons: [`missing required sections: [${missing.join(", ")}]`],
277
+ };
278
+ }
279
+ return { ok: true, reasons: [] };
280
+ }
281
+ function moduleStructuralDetail(result) {
282
+ if (result.ok)
283
+ return "module file is structurally complete";
284
+ return `module file is empty or has structural issues: ${result.reasons.join("; ")}`;
285
+ }
286
+ function pythonStructureOutsideStrings(source) {
287
+ const input = source.replace(/\r\n/g, "\n");
288
+ let output = "";
289
+ let index = 0;
290
+ let quote;
291
+ let triple = false;
292
+ let comment = false;
293
+ while (index < input.length) {
294
+ const char = input[index];
295
+ if (comment) {
296
+ if (char === "\n") {
297
+ comment = false;
298
+ output += "\n";
299
+ }
300
+ else
301
+ output += " ";
302
+ index += 1;
303
+ continue;
304
+ }
305
+ if (quote) {
306
+ if (char === "\\") {
307
+ output += " ";
308
+ if (index + 1 < input.length)
309
+ output += input[index + 1] === "\n" ? "\n" : " ";
310
+ index += 2;
311
+ continue;
312
+ }
313
+ if (triple && input.slice(index, index + 3) === quote.repeat(3)) {
314
+ output += " ";
315
+ index += 3;
316
+ quote = undefined;
317
+ triple = false;
318
+ continue;
319
+ }
320
+ if (!triple && char === quote) {
321
+ output += " ";
322
+ index += 1;
323
+ quote = undefined;
324
+ continue;
325
+ }
326
+ if (!triple && char === "\n")
327
+ return { text: output, stringsClosed: false };
328
+ output += char === "\n" ? "\n" : " ";
329
+ index += 1;
330
+ continue;
331
+ }
332
+ if (char === "#") {
333
+ comment = true;
334
+ output += " ";
335
+ index += 1;
336
+ continue;
337
+ }
338
+ if (char === "'" || char === '"') {
339
+ quote = char;
340
+ triple = input.slice(index, index + 3) === char.repeat(3);
341
+ output += triple ? " " : " ";
342
+ index += triple ? 3 : 1;
343
+ continue;
344
+ }
345
+ output += char;
346
+ index += 1;
347
+ }
348
+ return { text: output, stringsClosed: quote === undefined };
349
+ }
350
+ function pythonParseable(source) {
351
+ const normalized = source.replace(/\r\n/g, "\n");
352
+ if (!normalized.trim())
353
+ return false;
354
+ if (/^\s*(?:def|class|import|from)\b/m.test(normalized) === false)
355
+ return false;
356
+ const structural = pythonStructureOutsideStrings(normalized);
357
+ if (!structural.stringsClosed)
358
+ return false;
359
+ const text = structural.text;
360
+ const openParens = (text.match(/\(/g) ?? []).length;
361
+ const closeParens = (text.match(/\)/g) ?? []).length;
362
+ const openBrackets = (text.match(/\[/g) ?? []).length;
363
+ const closeBrackets = (text.match(/\]/g) ?? []).length;
364
+ const openBraces = (text.match(/\{/g) ?? []).length;
365
+ const closeBraces = (text.match(/\}/g) ?? []).length;
366
+ if (openParens !== closeParens)
367
+ return false;
368
+ if (openBrackets !== closeBrackets)
369
+ return false;
370
+ if (openBraces !== closeBraces)
371
+ return false;
372
+ return true;
373
+ }
374
+ /**
375
+ * Forbidden generated shared helper/factory namespaces for the self-contained
376
+ * pytest module contract. A self-contained testcase/test_*.py child must not
377
+ * import from generated shared namespaces such as `testcase_helpers`,
378
+ * `testcase.helpers`, or `testcase.factories`; those belong to the pytest plan
379
+ * node's shared resources, not to a per-module pytest script. Rejecting such
380
+ * imports early (before pytest collection) gives an actionable, recoverable
381
+ * incomplete-write-set signal carrying the exact module target path.
382
+ */
383
+ export const FORBIDDEN_GENERATED_IMPORT_NAMESPACES = [
384
+ "testcase_helpers",
385
+ "testcase.helpers",
386
+ "testcase.factories",
387
+ ];
388
+ const FORBIDDEN_GENERATED_IMPORT_PATTERN = /^\s*(?:from\s+(testcase_helpers|testcase\.helpers|testcase\.factories)\b|import\s+(testcase_helpers|testcase\.helpers|testcase\.factories)\b)/gm;
389
+ /**
390
+ * Scan Python source for imports from forbidden generated shared namespaces.
391
+ * Anchored at line start with a word boundary so `testcase.helpers_other` or a
392
+ * substring inside a docstring sentence is not falsely flagged. Returns the
393
+ * list of offending namespace module names (deduplicated, order-preserving).
394
+ */
395
+ export function findForbiddenGeneratedImports(source) {
396
+ const hits = [];
397
+ const seen = new Set();
398
+ for (const match of source.matchAll(FORBIDDEN_GENERATED_IMPORT_PATTERN)) {
399
+ const ns = (match[1] ?? match[2]);
400
+ if (!seen.has(ns)) {
401
+ seen.add(ns);
402
+ hits.push(ns);
403
+ }
404
+ }
405
+ return hits;
406
+ }
407
+ /**
408
+ * Looser Python validity check for shared helpers/factories emitted by the
409
+ * pytest plan node. Unlike pythonParseable, it does NOT require balanced
410
+ * brackets/braces: shared pytest resources legitimately contain fixture
411
+ * strings with unbalanced delimiters (e.g. a malformed-JSON test payload
412
+ * `return "{bad json"`). Only verifies the file is non-empty, declares a
413
+ * Python construct (def/class/import/from), and has balanced triple quotes.
414
+ */
415
+ function looksLikeValidPythonModule(source) {
416
+ const text = source.replace(/\r\n/g, "\n");
417
+ if (!text.trim())
418
+ return false;
419
+ if (/^\s*(?:def|class|import|from)\b/m.test(text) === false)
420
+ return false;
421
+ return pythonStructureOutsideStrings(text).stringsClosed;
422
+ }
423
+ export function buildOutputLimitRecoveryPrompt(input) {
424
+ return buildOutputLimitRecoverySection(input);
425
+ }
426
+ /**
427
+ * Build an inline `<retry_instruction>` block embedding the exact target
428
+ * paths. Used by {@link buildAttemptPrompt} so a continuation attempt does
429
+ * not depend on reading `.harness/**` (which is forbidden for Pi writers).
430
+ */
431
+ export function buildOutputLimitRecoverySection(input) {
432
+ const hasDiagnostics = !!input.diagnostics && Object.keys(input.diagnostics).length > 0;
433
+ const pathsBlock = hasDiagnostics
434
+ ? input.targetPaths
435
+ .map((p) => {
436
+ const reasons = (input.diagnostics?.[p] ?? []).slice(0, 3);
437
+ if (reasons.length === 0)
438
+ return ` - ${p}`;
439
+ const issueLines = reasons.map((r) => ` - ${r}`).join("\n");
440
+ return ` - ${p}\n issues:\n${issueLines}`;
441
+ })
442
+ .join("\n")
443
+ : input.targetPaths.length > 0
444
+ ? input.targetPaths.map((item) => ` - ${item}`).join("\n")
445
+ : " - (none)";
446
+ return [
447
+ "<retry_instruction>",
448
+ `OUTPUT_LIMIT_RECOVERY attempt=${input.attempt}/${input.maxAttempts}`,
449
+ `reason=${input.reason}`,
450
+ "target_paths_only:",
451
+ pathsBlock,
452
+ "Rules:",
453
+ "- Continue or repair ONLY listed paths; do not delete or shrink in-scope cases/rules/TPs.",
454
+ "- One file per write/edit; no chat dump of full bodies.",
455
+ "- Prefer edit/append for truncated files; rewrite a file only if unparseable or empty.",
456
+ ...(hasDiagnostics
457
+ ? ["- Fix the exact structural issues listed under each path; do not change unrelated content."]
458
+ : []),
459
+ "- After targets are complete, short IMPLEMENTATION_OUTCOME only.",
460
+ "- Do not mark already-satisfied if any target_path still missing or structurally broken.",
461
+ "- Preserve quality invariants: no scope shrink, no skip/xfail, no secret-shaped samples.",
462
+ "</retry_instruction>",
463
+ ].join("\n");
464
+ }
465
+ /**
466
+ * Load the most recent writer-progress facts from the run dir for a given
467
+ * generation writer task id, so the next attempt's prompt can embed concrete
468
+ * target paths instead of asking the model to read a forbidden `.harness/**`
469
+ * path. Returns undefined when no progress facts exist yet (first retry of
470
+ * a session, or a non-completeness failure).
471
+ */
472
+ export async function loadBackendTestWriterProgressForRetry(runDir, taskId) {
473
+ const role = backendTestWriterProgressRoleForTask(taskId);
474
+ if (!role)
475
+ return undefined;
476
+ const factsPath = path.join(runDir, "contracts", `backend-test-writer-progress-${role}.json`);
477
+ try {
478
+ const raw = await readFile(factsPath, "utf8");
479
+ return progressSchema.parse(JSON.parse(raw));
480
+ }
481
+ catch {
482
+ return undefined;
483
+ }
484
+ }
485
+ /**
486
+ * Per-shard-child completeness assessment for map_agent children
487
+ * (generate-backend-md-case-NNNN / generate-backend-pytest-case-NNNN).
488
+ *
489
+ * Unlike the workspace-wide {@link assessBackendTestMdWriterCompleteness} /
490
+ * {@link assessBackendTestPytestWriterCompleteness} gates (which run for the
491
+ * legacy single-node writers and for the post-map review/validate nodes), a
492
+ * sharded child owns ONLY the single file in its rendered writeSet. Running
493
+ * the workspace-wide gate mid-map would flag every not-yet-written sibling
494
+ * module as a recoverable miss and loop. This function scopes the gate to the
495
+ * child's own target file(s): md children are checked for structural
496
+ * completeness, pytest children for parseability. Sibling modules are ignored.
497
+ */
498
+ export async function assessBackendTestShardChildCompleteness(input) {
499
+ const role = input.role;
500
+ const targetPaths = input.writeSet
501
+ .map((entry) => entry.trim().replace(/\\/g, "/").replace(/^\.\//, ""))
502
+ .filter((entry) => entry.length > 0);
503
+ const issues = [];
504
+ const actualPaths = [];
505
+ const missingPaths = [];
506
+ const brokenPaths = [];
507
+ for (const target of targetPaths) {
508
+ // Rendered map-child writeSet entries are concrete (e.g.
509
+ // testcase/md/health.md / testcase/test_orders.py); glob-only entries are
510
+ // not produced for these children.
511
+ if (target.includes("*"))
512
+ continue;
513
+ const absolute = path.join(input.workspaceRoot, target);
514
+ if (!(await exists(absolute))) {
515
+ missingPaths.push(target);
516
+ issues.push({
517
+ code: "T3",
518
+ path: target,
519
+ detail: `shard child target ${target} was not written`,
520
+ recoverable: true,
521
+ });
522
+ continue;
523
+ }
524
+ actualPaths.push(target);
525
+ const body = await readFile(absolute, "utf8");
526
+ if (role === "md-generate") {
527
+ const structural = moduleStructurallyComplete(body);
528
+ if (!structural.ok) {
529
+ brokenPaths.push(target);
530
+ issues.push({
531
+ code: "T5",
532
+ path: target,
533
+ detail: moduleStructuralDetail(structural),
534
+ recoverable: true,
535
+ });
536
+ }
537
+ }
538
+ else {
539
+ if (!pythonParseable(body)) {
540
+ brokenPaths.push(target);
541
+ issues.push({
542
+ code: "T5",
543
+ path: target,
544
+ detail: "pytest script appears truncated or unparseable",
545
+ recoverable: true,
546
+ });
547
+ }
548
+ const forbidden = findForbiddenGeneratedImports(body);
549
+ if (forbidden.length > 0) {
550
+ if (!brokenPaths.includes(target))
551
+ brokenPaths.push(target);
552
+ issues.push({
553
+ code: "T5",
554
+ path: target,
555
+ detail: `forbidden import from ${forbidden.join(", ")} in ${target}; self-contained pytest module must not import generated shared helper/factory namespaces`,
556
+ recoverable: true,
557
+ });
558
+ }
559
+ }
560
+ }
561
+ const recoverableTargets = orderedUnique([...missingPaths, ...brokenPaths]);
562
+ const status = recoverableTargets.length > 0 || issues.length > 0 ? "RECOVERABLE" : "PASS";
563
+ return {
564
+ schemaId: BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID,
565
+ role,
566
+ status,
567
+ expectedPaths: orderedUnique(targetPaths),
568
+ actualPaths: orderedUnique(actualPaths),
569
+ missingPaths: orderedUnique(missingPaths),
570
+ brokenPaths: orderedUnique(brokenPaths),
571
+ targetPaths: recoverableTargets,
572
+ issues,
573
+ };
574
+ }
575
+ export async function assessBackendTestMdWriterCompleteness(workspaceRoot, layout) {
576
+ const resolved = layout ?? resolveBackendTestLayout(undefined);
577
+ const readmeRel = resolved.readmePath;
578
+ const issues = [];
579
+ const expectedPaths = [readmeRel];
580
+ const actualPaths = [];
581
+ const missingPaths = [];
582
+ const brokenPaths = [];
583
+ const readmePath = path.join(workspaceRoot, ...readmeRel.split("/"));
584
+ let readme = "";
585
+ if (!(await exists(readmePath))) {
586
+ missingPaths.push(readmeRel);
587
+ issues.push({
588
+ code: "T3",
589
+ path: readmeRel,
590
+ detail: "README.md is missing",
591
+ recoverable: true,
592
+ });
593
+ }
594
+ else {
595
+ actualPaths.push(readmeRel);
596
+ readme = await readFile(readmePath, "utf8");
597
+ if (!readme.includes("## Coverage Scope")) {
598
+ brokenPaths.push(readmeRel);
599
+ issues.push({
600
+ code: "T5",
601
+ path: readmeRel,
602
+ detail: "README.md is missing ## Coverage Scope",
603
+ recoverable: true,
604
+ });
605
+ }
606
+ if (!readme.includes("## Coverage Matrix") ||
607
+ !hasMarkdownTable(readme, "Rule Key")) {
608
+ if (!brokenPaths.includes(readmeRel)) {
609
+ brokenPaths.push(readmeRel);
610
+ }
611
+ issues.push({
612
+ code: "T5",
613
+ path: readmeRel,
614
+ detail: "README.md Coverage Matrix table is missing or broken",
615
+ recoverable: true,
616
+ });
617
+ }
618
+ }
619
+ const indexedStems = extractModuleStemsFromReadme(readme);
620
+ const existingModules = await listMarkdownModules(workspaceRoot, resolved);
621
+ const existingByStem = new Map(existingModules.map((rel) => [
622
+ normalizeBackendTestModuleStem(path.posix.basename(rel)),
623
+ rel,
624
+ ]));
625
+ for (const stem of indexedStems) {
626
+ const rel = `${resolved.markdownDir}/${stem}.md`;
627
+ expectedPaths.push(rel);
628
+ const existing = existingByStem.get(stem);
629
+ if (!existing) {
630
+ missingPaths.push(rel);
631
+ issues.push({
632
+ code: "T3",
633
+ path: rel,
634
+ detail: `module file missing for README index stem ${stem}`,
635
+ recoverable: true,
636
+ });
637
+ continue;
638
+ }
639
+ actualPaths.push(existing);
640
+ const body = await readFile(path.join(workspaceRoot, existing), "utf8");
641
+ const structural = moduleStructurallyComplete(body);
642
+ if (!structural.ok) {
643
+ brokenPaths.push(existing);
644
+ issues.push({
645
+ code: "T5",
646
+ path: existing,
647
+ detail: moduleStructuralDetail(structural),
648
+ recoverable: true,
649
+ });
650
+ }
651
+ }
652
+ for (const rel of existingModules) {
653
+ if (!actualPaths.includes(rel))
654
+ actualPaths.push(rel);
655
+ const body = await readFile(path.join(workspaceRoot, rel), "utf8");
656
+ const structural = moduleStructurallyComplete(body);
657
+ if (!structural.ok && !brokenPaths.includes(rel)) {
658
+ brokenPaths.push(rel);
659
+ issues.push({
660
+ code: "T5",
661
+ path: rel,
662
+ detail: moduleStructuralDetail(structural),
663
+ recoverable: true,
664
+ });
665
+ }
666
+ }
667
+ if (existingModules.length === 0 &&
668
+ indexedStems.length === 0 &&
669
+ (await exists(readmePath))) {
670
+ issues.push({
671
+ code: "T3",
672
+ detail: "no module Markdown files were produced",
673
+ recoverable: true,
674
+ });
675
+ }
676
+ const targetPaths = orderedUnique([...missingPaths, ...brokenPaths]);
677
+ const nonRecoverable = issues.some((issue) => !issue.recoverable);
678
+ const status = nonRecoverable
679
+ ? "NON_RECOVERABLE"
680
+ : targetPaths.length > 0 || issues.length > 0
681
+ ? "RECOVERABLE"
682
+ : "PASS";
683
+ return {
684
+ schemaId: BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID,
685
+ role: "md-generate",
686
+ status,
687
+ expectedPaths: orderedUnique(expectedPaths),
688
+ actualPaths: orderedUnique(actualPaths),
689
+ missingPaths: orderedUnique(missingPaths),
690
+ brokenPaths: orderedUnique(brokenPaths),
691
+ targetPaths,
692
+ issues,
693
+ };
694
+ }
695
+ export async function assessBackendTestPytestWriterCompleteness(workspaceRoot, layout) {
696
+ const resolved = layout ?? resolveBackendTestLayout(undefined);
697
+ const issues = [];
698
+ const expectedPaths = [];
699
+ const actualPaths = [];
700
+ const missingPaths = [];
701
+ const brokenPaths = [];
702
+ const modules = await listMarkdownModules(workspaceRoot, resolved);
703
+ for (const moduleRel of modules) {
704
+ const expected = expectedBackendTestPytestScriptForMarkdownModule(path.posix.basename(moduleRel), resolved);
705
+ expectedPaths.push(expected);
706
+ const absolute = path.join(workspaceRoot, expected);
707
+ if (!(await exists(absolute))) {
708
+ missingPaths.push(expected);
709
+ issues.push({
710
+ code: "T3",
711
+ path: expected,
712
+ detail: `mapped pytest script missing for ${moduleRel}`,
713
+ recoverable: true,
714
+ });
715
+ continue;
716
+ }
717
+ actualPaths.push(expected);
718
+ const source = await readFile(absolute, "utf8");
719
+ if (!pythonParseable(source)) {
720
+ brokenPaths.push(expected);
721
+ issues.push({
722
+ code: "T5",
723
+ path: expected,
724
+ detail: "pytest script appears truncated or unparseable",
725
+ recoverable: true,
726
+ });
727
+ continue;
728
+ }
729
+ const forbidden = findForbiddenGeneratedImports(source);
730
+ if (forbidden.length > 0) {
731
+ brokenPaths.push(expected);
732
+ issues.push({
733
+ code: "T5",
734
+ path: expected,
735
+ detail: `forbidden import from ${forbidden.join(", ")} in ${expected}; self-contained pytest module must not import generated shared helper/factory namespaces`,
736
+ recoverable: true,
737
+ });
738
+ continue;
739
+ }
740
+ const markdown = await readFile(path.join(workspaceRoot, moduleRel), "utf8");
741
+ const caseIds = orderedUnique([...markdown.matchAll(/\bBE-[A-Z0-9_-]+-\d{2,3}\b/g)].map((item) => item[0]));
742
+ const primaryHints = orderedUnique([
743
+ ...markdown.matchAll(/primary\s*symbol\s*[::]\s*`?([A-Za-z0-9_]+)`?/gi),
744
+ ].map((item) => item[1]));
745
+ for (const symbol of primaryHints) {
746
+ if (!source.includes(symbol)) {
747
+ brokenPaths.push(expected);
748
+ issues.push({
749
+ code: "T5",
750
+ path: expected,
751
+ detail: `primary symbol ${symbol} not found in mapped script`,
752
+ recoverable: true,
753
+ });
754
+ break;
755
+ }
756
+ }
757
+ if (caseIds.length > 0 &&
758
+ !caseIds.some((caseId) => source.includes(caseId) || source.includes(caseId.replaceAll("-", "_")))) {
759
+ brokenPaths.push(expected);
760
+ issues.push({
761
+ code: "T5",
762
+ path: expected,
763
+ detail: "no Markdown Case ID found in mapped pytest script",
764
+ recoverable: true,
765
+ });
766
+ }
767
+ }
768
+ const targetPaths = orderedUnique([...missingPaths, ...brokenPaths]);
769
+ const status = targetPaths.length > 0 || issues.length > 0 ? "RECOVERABLE" : "PASS";
770
+ return {
771
+ schemaId: BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID,
772
+ role: "pytest-generate",
773
+ status,
774
+ expectedPaths: orderedUnique(expectedPaths),
775
+ actualPaths: orderedUnique(actualPaths),
776
+ missingPaths: orderedUnique(missingPaths),
777
+ brokenPaths: orderedUnique(brokenPaths),
778
+ targetPaths,
779
+ issues,
780
+ };
781
+ }
782
+ export function classifyBackendTestWriterCompletenessFailure(progress) {
783
+ if (progress.status === "PASS") {
784
+ return {
785
+ failureCategory: "invalid-output",
786
+ reason: "T4",
787
+ recoverable: false,
788
+ };
789
+ }
790
+ if (progress.status === "NON_RECOVERABLE") {
791
+ return {
792
+ failureCategory: "invalid-output",
793
+ reason: "T6",
794
+ recoverable: false,
795
+ };
796
+ }
797
+ const preferred = progress.issues.find((issue) => issue.code === "T5")?.code ??
798
+ progress.issues.find((issue) => issue.code === "T3")?.code ??
799
+ progress.issues.find((issue) => issue.code === "T4")?.code ??
800
+ "T3";
801
+ return {
802
+ failureCategory: "incomplete-write-set",
803
+ reason: preferred,
804
+ recoverable: true,
805
+ };
806
+ }
807
+ export async function writeBackendTestWriterProgressArtifacts(input) {
808
+ const contractsDir = path.join(input.runDir, "contracts");
809
+ await mkdir(contractsDir, { recursive: true });
810
+ const factsPath = path.join(contractsDir, `backend-test-writer-progress-${input.progress.role}.json`);
811
+ const parsed = progressSchema.parse(input.progress);
812
+ await writeFile(factsPath, JSON.stringify(parsed, null, 2), "utf8");
813
+ if (input.progress.status === "PASS") {
814
+ return { factsPath };
815
+ }
816
+ const reportsDir = path.join(input.runDir, "reports");
817
+ await mkdir(reportsDir, { recursive: true });
818
+ const reportPath = path.join(reportsDir, BACKEND_TEST_OUTPUT_LIMIT_RECOVERY_REPORT);
819
+ const attempt = input.attempt ?? 1;
820
+ const maxAttempts = input.maxAttempts ?? 3;
821
+ const classification = classifyBackendTestWriterCompletenessFailure(input.progress);
822
+ const body = [
823
+ "# Backend-test Output Limit Recovery",
824
+ "",
825
+ `- Role: ${input.progress.role}`,
826
+ `- Status: ${input.progress.status}`,
827
+ `- Attempt: ${attempt}/${maxAttempts}`,
828
+ `- Reason: ${classification.reason}`,
829
+ `- Recoverable: ${classification.recoverable}`,
830
+ "",
831
+ "## Target paths",
832
+ "",
833
+ ...(input.progress.targetPaths.length
834
+ ? input.progress.targetPaths.map((item) => `- ${item}`)
835
+ : ["- (none)"]),
836
+ "",
837
+ "## Issues",
838
+ "",
839
+ ...(input.progress.issues.length
840
+ ? input.progress.issues.map((issue) => `- [${issue.code}] ${issue.path ?? "(workspace)"}: ${issue.detail}`)
841
+ : ["- None"]),
842
+ "",
843
+ `<!-- sha256:${createHash("sha256").update(JSON.stringify(parsed)).digest("hex")} -->`,
844
+ "",
845
+ ].join("\n");
846
+ await writeFile(reportPath, body, "utf8");
847
+ return { factsPath, reportPath };
848
+ }
849
+ export function isBackendTestCompletenessRetryCandidate(task) {
850
+ if (task.executor !== "pi" || task.role !== "implementer")
851
+ return false;
852
+ if (task.toolProfile !== "write" || task.writePolicy !== "exclusive") {
853
+ return false;
854
+ }
855
+ if ((task.writeSet?.length ?? 0) === 0)
856
+ return false;
857
+ if (task.writerOutcomePolicy?.type !== "implementation-outcome-v1") {
858
+ return false;
859
+ }
860
+ return (task.id === "generate-backend-md-cases-pi" ||
861
+ task.id === "generate-backend-pytest-pi" ||
862
+ task.id === "generate-backend-md-plan-pi" ||
863
+ task.id === "generate-backend-pytest-plan-pi" ||
864
+ // Plan D gap-fill patch writers share the same Completeness Gate retry
865
+ // contract as full-chain writers.
866
+ task.id === "patch-backend-readme-matrix-pi" ||
867
+ (task.id?.startsWith("patch-backend-md-case-") ?? false) ||
868
+ (task.id?.startsWith("patch-backend-pytest-case-") ?? false) ||
869
+ (task.id?.startsWith("generate-backend-md-case-") ?? false) ||
870
+ (task.id?.startsWith("generate-backend-pytest-case-") ?? false));
871
+ }
872
+ /**
873
+ * Is this task a materialized map_agent shard child (as opposed to the legacy
874
+ * single-node generator)? Shard children must scope the Completeness Gate to
875
+ * their own rendered writeSet rather than the whole workspace.
876
+ */
877
+ export function isBackendTestShardChildTask(task) {
878
+ return Boolean(task.id?.startsWith("generate-backend-md-case-") ||
879
+ task.id?.startsWith("generate-backend-pytest-case-"));
880
+ }
881
+ /**
882
+ * Is this task the README-only plan node of the map-sharded md topology?
883
+ * The plan node writes testcase/md/README.md alone; module case cards are
884
+ * produced by the downstream map_agent children, so the Completeness Gate
885
+ * must NOT require module files to exist at plan time.
886
+ */
887
+ export function isBackendTestMdPlanTask(task) {
888
+ return task.id === "generate-backend-md-plan-pi";
889
+ }
890
+ /**
891
+ * Is this task the shared-resources plan node of the map-sharded pytest
892
+ * topology? The plan node writes helpers/factories only; per-module pytest
893
+ * scripts are produced by the downstream map_agent children, so the Gate
894
+ * must NOT require mapped pytest scripts to exist at plan time.
895
+ */
896
+ export function isBackendTestPytestPlanTask(task) {
897
+ return task.id === "generate-backend-pytest-plan-pi";
898
+ }
899
+ /**
900
+ * Plan-node completeness for the md topology: verify the README itself is
901
+ * structurally complete (Coverage Scope, Coverage Matrix, a non-empty module
902
+ * index), WITHOUT requiring the indexed module files to exist yet — those are
903
+ * written by the downstream map_agent shard children.
904
+ */
905
+ export async function assessBackendTestMdPlanCompleteness(workspaceRoot, layout) {
906
+ const resolvedPlan = layout ?? resolveBackendTestLayout(undefined);
907
+ const planReadmeRel = resolvedPlan.readmePath;
908
+ const issues = [];
909
+ const expectedPaths = [planReadmeRel];
910
+ const actualPaths = [];
911
+ const missingPaths = [];
912
+ const brokenPaths = [];
913
+ const readmePath = path.join(workspaceRoot, ...planReadmeRel.split("/"));
914
+ if (!(await exists(readmePath))) {
915
+ missingPaths.push(planReadmeRel);
916
+ issues.push({
917
+ code: "T3",
918
+ path: planReadmeRel,
919
+ detail: "README.md is missing",
920
+ recoverable: true,
921
+ });
922
+ }
923
+ else {
924
+ actualPaths.push(planReadmeRel);
925
+ const readme = await readFile(readmePath, "utf8");
926
+ if (!readme.includes("## Coverage Scope")) {
927
+ brokenPaths.push(planReadmeRel);
928
+ issues.push({
929
+ code: "T5",
930
+ path: planReadmeRel,
931
+ detail: "README.md is missing ## Coverage Scope",
932
+ recoverable: true,
933
+ });
934
+ }
935
+ if (!readme.includes("## Coverage Matrix") ||
936
+ !hasMarkdownTable(readme, "Rule Key")) {
937
+ if (!brokenPaths.includes(planReadmeRel)) {
938
+ brokenPaths.push(planReadmeRel);
939
+ }
940
+ issues.push({
941
+ code: "T5",
942
+ path: planReadmeRel,
943
+ detail: "README.md Coverage Matrix table is missing or broken",
944
+ recoverable: true,
945
+ });
946
+ }
947
+ // The README must advertise a non-empty module index so the downstream
948
+ // manifest shell has stems to shard; the indexed module files themselves
949
+ // are produced by map_agent children and are NOT required here.
950
+ const stemInspection = inspectModuleStemsFromReadme(readme);
951
+ const indexedStems = stemInspection.validStems;
952
+ for (const structureIssue of stemInspection.structureIssues) {
953
+ if (!brokenPaths.includes(planReadmeRel)) {
954
+ brokenPaths.push(planReadmeRel);
955
+ }
956
+ issues.push({
957
+ code: "T5",
958
+ path: planReadmeRel,
959
+ detail: structureIssue,
960
+ recoverable: true,
961
+ });
962
+ }
963
+ for (const invalid of stemInspection.invalid) {
964
+ if (!brokenPaths.includes(planReadmeRel)) {
965
+ brokenPaths.push(planReadmeRel);
966
+ }
967
+ issues.push({
968
+ code: "T5",
969
+ path: planReadmeRel,
970
+ detail: `${invalid.reasonCode}: ${invalid.normalized}; use a stable lowercase business resource/domain stem`,
971
+ recoverable: true,
972
+ });
973
+ }
974
+ if (indexedStems.length === 0) {
975
+ if (!brokenPaths.includes(planReadmeRel)) {
976
+ brokenPaths.push(planReadmeRel);
977
+ }
978
+ issues.push({
979
+ code: "T5",
980
+ path: planReadmeRel,
981
+ detail: "README.md module index is empty; downstream map_agent has no stems to shard",
982
+ recoverable: true,
983
+ });
984
+ }
985
+ }
986
+ const targetPaths = orderedUnique([...missingPaths, ...brokenPaths]);
987
+ const status = targetPaths.length > 0 ? "RECOVERABLE" : "PASS";
988
+ return {
989
+ schemaId: BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID,
990
+ role: "md-generate",
991
+ status,
992
+ expectedPaths: orderedUnique(expectedPaths),
993
+ actualPaths: orderedUnique(actualPaths),
994
+ missingPaths: orderedUnique(missingPaths),
995
+ brokenPaths: orderedUnique(brokenPaths),
996
+ targetPaths,
997
+ issues,
998
+ };
999
+ }
1000
+ /**
1001
+ * Plan-node completeness for the pytest topology: verify the shared
1002
+ * helpers/factories resources were produced and are Python-parseable, WITHOUT
1003
+ * requiring per-module pytest scripts to exist yet — those are written by the
1004
+ * downstream map_agent shard children.
1005
+ */
1006
+ export async function assessBackendTestPytestPlanCompleteness(workspaceRoot, layout) {
1007
+ const resolvedPlan = layout ?? resolveBackendTestLayout(undefined);
1008
+ const issues = [];
1009
+ const expectedPaths = [];
1010
+ const actualPaths = [];
1011
+ const missingPaths = [];
1012
+ const brokenPaths = [];
1013
+ // Discover shared pytest resources under <testRoot>/**/helpers/** and
1014
+ // <testRoot>/**/factories/** (the plan node writeSet globs).
1015
+ const candidates = [];
1016
+ for (const dir of [`${resolvedPlan.testRoot}/helpers`, `${resolvedPlan.testRoot}/factories`]) {
1017
+ const absolute = path.join(workspaceRoot, dir);
1018
+ if (await exists(absolute)) {
1019
+ for (const file of await listPythonFiles(absolute)) {
1020
+ candidates.push(`${dir}/${file}`);
1021
+ }
1022
+ }
1023
+ }
1024
+ if (candidates.length === 0) {
1025
+ issues.push({
1026
+ code: "T3",
1027
+ detail: "no shared helpers/factories were produced; pytest plan must emit at least one shared resource",
1028
+ recoverable: true,
1029
+ });
1030
+ }
1031
+ for (const rel of candidates) {
1032
+ expectedPaths.push(rel);
1033
+ actualPaths.push(rel);
1034
+ const body = await readFile(path.join(workspaceRoot, rel), "utf8");
1035
+ if (!looksLikeValidPythonModule(body)) {
1036
+ brokenPaths.push(rel);
1037
+ issues.push({
1038
+ code: "T5",
1039
+ path: rel,
1040
+ detail: "shared pytest resource appears truncated or unparseable",
1041
+ recoverable: true,
1042
+ });
1043
+ }
1044
+ }
1045
+ const targetPaths = orderedUnique([...missingPaths, ...brokenPaths]);
1046
+ const status = targetPaths.length > 0 || issues.length > 0 ? "RECOVERABLE" : "PASS";
1047
+ return {
1048
+ schemaId: BACKEND_TEST_WRITER_PROGRESS_SCHEMA_ID,
1049
+ role: "pytest-generate",
1050
+ status,
1051
+ expectedPaths: orderedUnique(expectedPaths),
1052
+ actualPaths: orderedUnique(actualPaths),
1053
+ missingPaths: orderedUnique(missingPaths),
1054
+ brokenPaths: orderedUnique(brokenPaths),
1055
+ targetPaths,
1056
+ issues,
1057
+ };
1058
+ }