@tea-agent/loop-agent 0.39.0-beta.14 → 0.39.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # 更新日志
2
2
 
3
3
  ## [Unreleased]
4
+ - 0.39.0-beta.15(frontend-node dogfood):修复自动前端路由修改 task.json 后未同步 Task Contract,导致批准阶段反复出现 externally-modified、contract binding drift 和 DAG 启动失败的问题;同时修复 adopt/import refresh 丢失 source fidelity ledger hash 的问题。
4
5
  - 0.39.0-beta.14(frontend-node dogfood):plan-pi 三段分段会话 + coverage 需求批次切片(4/批、零进度减半)、finalize 收据修复环(聚合诊断+修复 JSON)、record_* 边界校验左移(VT 重复/writeSet/交互 VT 引用/规范需求 id/可疑 symbol)、编译装配 last-wins(组件按 purpose 去重修正)、review-context 授权面扩展至 VT 测试文件、设计评审修订降级为 admission advisory。
5
6
  - 前端 DAG 极端环境加固(16KB 输出 / 120KB 上下文真实冒烟,r2-r5 验证):`frontend-contract-pi` 改为消费编译后的 ledger 输入块(`<frontend_contract_input>`,12KB 上限、cap ladder、requirement id 永不丢)并移除 read 工具,以增量 `record_*` 提交为唯一输出模式(OUTPUT BUDGET DISCIPLINE),修复极端小输出窗口下模型反复 read 源文件空转 1h54m 超时的问题(r3 起 contract 3m54s 正常完成、37 次 record_* / 0 次 read);plan/contract 的 `record_*` 工具支持每 message 最多 5 条批量提交并加 1s 调用间隔,rate-limit 退避上限提高到 60s,缓解密集小调用触发第三方网关限流;修复 fragment-inventory 对 V4 标题式 AC(`#### AC-NNN`)的双重 emit 缺陷(同一标题行被 section 入口与正文 heading 分支各切一次,30 个 AC 结构性产生 30 个 duplicate)。
6
7
 
@@ -280,12 +280,12 @@ export async function generateTaskDagUseCase(input) {
280
280
  requestPayloadSha256: randomUUID().replaceAll("-", "").padEnd(64, "0"),
281
281
  });
282
282
  }
283
- const candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
283
+ let candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
284
284
  outputPath: parsed.outputPath,
285
285
  template: "standard-dag",
286
286
  rerunFeedback: parsed.rerunFeedback,
287
287
  });
288
- const candidateValidateSummary = await validateDagUseCase(buildValidateInput(repoRoot, candidateResult.outputPath, parsed));
288
+ let candidateValidateSummary = await validateDagUseCase(buildValidateInput(repoRoot, candidateResult.outputPath, parsed));
289
289
  const profileRouting = await resolveProfileRouting(repoRoot, parsed, candidateValidateSummary.governanceProfile ?? {
290
290
  profile: "standard",
291
291
  process: [],
@@ -322,6 +322,30 @@ export async function generateTaskDagUseCase(input) {
322
322
  taskKind: "frontend-implementation",
323
323
  dagFallbackReason: "Automatically classified as a high-confidence frontend implementation task.",
324
324
  });
325
+ // taskKind participates in task.json's canonical hash. Adopt the
326
+ // automatic route before exposing this DAG, then regenerate it so its
327
+ // frozen taskContractBinding points at the adopted revision.
328
+ const state = await observeTaskContract({
329
+ repoRoot,
330
+ taskId: parsed.taskId,
331
+ });
332
+ if (!state.ref || !state.observedCanonicalHash) {
333
+ throw new Error("automatic frontend routing could not reconcile the managed Task Contract");
334
+ }
335
+ await adoptTaskContract({
336
+ repoRoot,
337
+ taskId: parsed.taskId,
338
+ expectedRevision: state.ref.revision,
339
+ expectedObservedHash: state.observedCanonicalHash,
340
+ requestId: `automatic-frontend-route-${parsed.taskId}-${randomUUID()}`,
341
+ requestPayloadSha256: randomUUID().replaceAll("-", "").padEnd(64, "0"),
342
+ });
343
+ candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
344
+ outputPath: parsed.outputPath,
345
+ template: "standard-dag",
346
+ rerunFeedback: parsed.rerunFeedback,
347
+ });
348
+ candidateValidateSummary = await validateDagUseCase(buildValidateInput(repoRoot, candidateResult.outputPath, parsed));
325
349
  }
326
350
  }
327
351
  const initResult = profileRouting.selectedTemplate === candidateResult.template
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.39.0-beta.14",
4
- "gitSha": "9d8bebca76a2608d9b38a1af1f379fd5fe5b04b0",
5
- "builtAt": "2026-08-30T09:13:51.707Z"
3
+ "version": "0.39.0-beta.15",
4
+ "gitSha": "188a3e304d6301cac9e02e309e47fae29bb05be2",
5
+ "builtAt": "2026-08-30T12:30:20.874Z"
6
6
  }
@@ -90,6 +90,10 @@ export async function adoptTaskContract(input) {
90
90
  requirementBytes: bytes.requirementBytes,
91
91
  constraintsBytes: bytes.constraintsBytes,
92
92
  referenceManifestBytes: bytes.referenceManifestBytes,
93
+ ...(state.ref?.sourceHashes.requirementLedgerSha256 &&
94
+ bytes.requirementLedgerBytes !== null
95
+ ? { requirementLedgerBytes: bytes.requirementLedgerBytes }
96
+ : {}),
93
97
  });
94
98
  const taskConfigSha256 = computeTaskConfigSha256(fullConfig);
95
99
  const canonicalHash = computeCanonicalHash({
@@ -45,6 +45,10 @@ export async function refreshManagedContractAfterImport(input) {
45
45
  requirementBytes: bytes.requirementBytes,
46
46
  constraintsBytes: bytes.constraintsBytes,
47
47
  referenceManifestBytes: bytes.referenceManifestBytes,
48
+ ...(state2.ref.sourceHashes.requirementLedgerSha256 &&
49
+ bytes.requirementLedgerBytes !== null
50
+ ? { requirementLedgerBytes: bytes.requirementLedgerBytes }
51
+ : {}),
48
52
  });
49
53
  const taskConfigSha256 = computeTaskConfigSha256(fullConfig);
50
54
  const canonicalHash = computeCanonicalHash({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.39.0-beta.14",
3
+ "version": "0.39.0-beta.15",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -106,4 +106,4 @@
106
106
  "vitest": "^3.2.4"
107
107
  },
108
108
  "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
109
- }
109
+ }