Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
b4113bb
wip: #199 交付A 开工
steponeerror Oct 25, 2026
172b74c
feat(#199 A1): P15 预算四界环内执法——budget.mjs 单源+引擎检查点+闭集 13 词
steponeerror Oct 25, 2026
0f07471
feat(#199 A2): 月度 kill switch 准入——双面共享 budget.mjs,拒跑留痕
steponeerror Oct 25, 2026
2ba2058
feat(#199 A3): 台账双写面加锁——python fcntl/lib.sh flock 同锁域,并发零丢行
steponeerror Oct 25, 2026
b4e6994
feat(#199 A4): 重复调用哈希——双面注入第 3 次同参拦(code=repeat_storm),计数入 09-budget.…
steponeerror Oct 25, 2026
6bb2836
feat(#199 A5): 09-budget.json 预算读数工件+G_CLOSE 回声哨扩展(读数≤生效帽对拍)
steponeerror Oct 25, 2026
b00ad90
docs(#199 交付A): CHANGELOG 双语条+A-REPORT 收口报告(交付A 五件全绿)
steponeerror Oct 25, 2026
1434b75
docs(#199 交付A): 补 CHANGELOG 双语条(m008 修单 P1=b00ad909 虚报)+A-REPORT 勘误
steponeerror Oct 25, 2026
7ac7c8d
merge(#199 交付A): P15 预算四界环内执法+月度 kill switch(merger 28621064 复算停合→P1 …
steponeerror Oct 25, 2026
68a36a0
wip: #199 交付B 开工
steponeerror Oct 25, 2026
0dc9250
#199 交付B:跨轮通道熔断器(P16)——breaker.mjs+ToolHost 单层接线+09-budget 快照
steponeerror Oct 25, 2026
41a0c87
#199 交付B 典章收口(A+B 同批):P15/P16 翻已有+D-5 措辞与挂点+建议区两行删+GLOSSARY 铸词+CHANGE…
steponeerror Oct 25, 2026
796e008
wip→收口: #199 交付B B-REPORT(交付清单/commit链/门数字含红期/自决十项/遗留)
steponeerror Oct 25, 2026
42b0f00
merge(#199 交付B): P16 跨轮通道熔断器+典章同批收口(merger 独立复算:六门亲跑对账+红测三件重放 31/31;零…
steponeerror Oct 25, 2026
370c3c6
review(#199): 双轴终审修单——STANDARD.md 序言计数去硬编码(P1,典章滞后族)+DESIGN.md 一词一拼对齐…
steponeerror Oct 25, 2026
3e52033
fix(#199): 墙钟帽=0 语义钉死零预算即拒——CI 同毫秒首步边界竞态假绿(budget.mjs 特例+纯函数红先绿后钉+CHA…
steponeerror Oct 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions A-REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# PR3b 交付 A 实现报告 — 票 #199「P15 预算四界」(#199 交付A)

- 工作树:`.worktrees/pr3b-a`,分支 `feature/pr3b-a`,基 `master=e952c584`
- 实现者:SDD fresh implementer(交付 B/熔断器 P16 不在本任务,未触碰)
- 收口时间:2026-10-25

## 交付清单(A1–A5 全落)

| 交付物 | 内容 | commit |
|---|---|---|
| A1 四界环内执法 | 新模块 `ops/agent/pipeline/budget.mjs`(六旋钮单源+纯函数);`runModelStage` ①调用数帽/③墙钟逐假设前查、②token/④花费结算后查;`runStages` 步边界③墙钟;违界 `fatalBudget` 直穿不重试不降级(宁少算);ERROR_CODES 9→13 词 | `172b74c7` |
| A2 月度 kill switch 准入 | `monthNow`/`monthSpendOfLedgerText`/`admitMonthly` 纯函数;pipeline.mjs(mkCtx 后、建目录前)与 agent.mjs runRound(legacy 面)双面共享 budget.mjs 准入;拒跑=`code=budget_monthly` 信封+exit 1+`appendRefusalTrace` 台账留痕行(锁内);无台账=0 起步;缺 cost 行跳过不猜 | `0f074717` |
| A3 台账双写面加锁 | `_ops_store.append_ledger` 持 `_ledger_lock()`(fcntl LOCK_EX,#139 判例,锁文件常驻不删);lib.sh `ledger_append` 头建+追加整段进 `flock "$LEDGER_FILE.lock"`;月度读面共享同锁;契约第 18 哨跨语言锁路径对拍;backend 并发测试 2×40=80 行零丢 | `2ba20582` |
| A4 重复调用哈希 | `canonicalJson`/`dupKey`(sha256 前 16 hex)/`dupRecord`/`dupTop` 纯函数;ToolHost.beforeToolCall 与 mkMicroprobeHost(微探针)双注入;第 3 次同参拦=`code=repeat_storm` 结构化信封(引 01:59 同参白烧判例;合法≤2 次重试不受影响;`limit=0` 停用) | `b4e6994c` |
| A5 09-budget.json 工件+G_CLOSE 扩展 | CLOSE 步先于 pkg 早退写工件(七旋钮生效值+usage/model_calls/wall_s/dup_top3/monthly 读数);G_CLOSE inputs+=09-budget.json,形状+读数≤帽回声哨(防工件漂移,非二次执法);golden 桩同步(cases.json 钉七旋钮+model_calls=4+monthly.ok);工件清单测试收录 | `6bb2836f` |

## Commit 链

```
b4113bb2 wip: #199 交付A 开工(占位防超时丢工)
172b74c7 feat(#199 A1): 预算四界环内执法
0f074717 feat(#199 A2): 月度 kill switch 双面准入
2ba20582 feat(#199 A3): 台账双写面加锁(双侧)
b4e6994c feat(#199 A4): 重复调用哈希双面注入
6bb2836f feat(#199 A5): 09-budget.json 工件+G_CLOSE 回声哨
<CHANGELOG commit>(本报告+CHANGELOG 同批)
```

## 各门数字(红期→绿期)

| 门 | 红期(真红) | 绿期 |
|---|---|---|
| selftest-pipeline(node) | A1: 63/5;A2: 68/4;A3: 见 backend 红行;A4: 72/3;A5: 74/3 | **77/0** |
| selftest-contract | —(新哨随批落地) | **18/0** |
| selftest-t4 | — | **58/0** |
| golden(run-golden) | — | **9/0** |
| standard-check | — | **OK=48 FAIL=0**(条文14 金标3 建议12 挂点30 原语22 已有10/半缺9/缺3) |
| selftest.sh 全量 | — | **115/0** |
| backend pytest(相关子集:test_ops_store/test_ops_read/core/test_api_update/core/test_startup) | A3 并发红:2×40 追加实得 40 行(丢行近半) | **65 passed**(含新并发零丢例) |

红测真红记录:每交付物均先写测→跑红→实现→绿。A3 红期为 backend 并发探针实测丢行(期望 80 实得 40);A1 红期 5 例(budget.mjs 不存在+执法缺位);A2 红期 4 例(monthNow 未落);A4 红期 3 例(canonicalJson 未落/拦截面缺);A5 红期 3 例(工件缺+inputs 缺+复评缺)。

## 偏离与理由

1. **ERROR_CODES 一次性 9→13 词(A1 批,非逐交付物)**:闭集扩展是交付A 一体的契约面(spec 验收门 3 明示 A 增四码);生产者分批落地,单源闭集一次成形避免三次改同一断言。channel_open 属交付 B,未加。
2. **BUDGET_KNOBS 六旋钮 A1 一次全录**:单一旋钮面(消费方逐批接线),契约扫描器面 24→30 一次对拍,测试 A1 即钉全默认值。
3. **golden 桩同步=cases.json 钉工件断言,无 GOLDENFAUX 常量**:现场核实仓内不存在 GOLDENFAUX 常量(grep 零命中),golden 桩的真实现状=run-golden.mjs 读 cases.json 断言;已按 #189 conflict 字段判例同形落 cases.json(pipeline_health_full_faux += 09-budget.json,七旋钮值+model_calls=4+monthly.ok=true+三读数面 matches)。spec 词汇以现场为准。
4. **P15 典章面(STANDARD.md:29/:103/:154-155、DESIGN.md:74、GLOSSARY 三词)未在本批**:spec「典章流程」节写明该面为 A+B 共享收口;任务令明确要求的典章面仅 CHANGELOG。留待 B 落地后一次收口(P15 半缺→在 + P16 同批),避免 B 未实现时翻正 P16 语境。**遗留项,见下。**
5. **t4 内进程 runRound 读工作树 docs/ops/ledger.md**(A2 起读月度面):文件缺席=0 起步,与生产语义一致;golden/contract 已显式重定向 LEDGER_FILE,无跨测试污染。
6. **A2 准入语义「等号放行」**:`projected=spend+est ≤ cap` 即跑(admitMonthly ok=projected<=cap)。spec 未钉等号归属;取等号放行与 G_DISPATCH `≤ cap+1e-9` 先例一致(宁少算不拦边界内)。

## 遗留

- **P15 典章翻正 + P16 典章面 + GLOSSARY「预算四界/双点执法/调用哈希」铸词**:交付 B 落地后同批收口(spec 典章流程节;偏离 4)。
- **CHANGELOG 双语条**:原计划随 b00ad909 落但该 commit 实只含本报告(虚报,merger P1 拦下);已由主会话单写者补 commit(勘误本行,见后续 docs commit)。
- 生产激活注记:六旋钮经 `_ops_rounds._SPAWN_ENV_PREFIXES=("OPS_","PI_")` 自动进 spawn 白名单(C4 面零改动);`OPS_PIPELINE_MONTHLY_CAP_CNY` 默认 30 即生效,拒跑面留痕行经 lib.sh flock 同锁域。
- 冒烟建议(合并后):真跑一轮 health 确认 09-budget.json 落盘 + 台账 memory_peak_bytes 行(下轮自然落)同场。

## 环境注记

- worktree 无 venv/node_modules;node 测试用 symlink `ops/agent/node_modules → 主仓`(未提交,.git/info/exclude 已忽略);backend 测试用主仓 venv。
- **判例:worktree 内 sandbox_assert 跑 `git status --porcelain -- backend/ frontend/`,backend 未提交改动会让全部全轮测试假红(8!==10 门)——跑 node 自测前 backend/front 必须干净**(A3 期间实踩,~30min)。
57 changes: 57 additions & 0 deletions B-REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# B-REPORT — #199 交付B(P16 跨轮通道熔断器)

分支 feature/pr3b-b(worktree .worktrees/pr3b-b),基 7ac7c8d8(交付A 已合入)。spec=/tmp/pr3b-spec.md。

## 交付清单

1. **ops/agent/tools/breaker.mjs(新)**:纯核+有态壳。
- 纯核:`BREAKER_CHANNELS` 恰五员{gh_search,web_read,web_search,rss_parse,fetch_url};`BREAKER_COUNTED_CODES` 恰三员{channel_missing,channel_auth,quota}(宁少算:transient/gh_error/io_error/http_error/network 不计);`parseBreakerState` 坏 JSON/错版本/野通道/野状态词/负 consec→null=fail-closed 重置闭路;`verdictFor`(closed→allow / open 冷却未到→block retryAfterS / open 已到→probe / half_open→block probe_in_flight);`grantProbe`(open→half_open **先落盘再放行**,探活名额持久);`applyResult`(closed 成功 consec=0=零写;半开成功→recovered 清零;半开失败→重开新整窗;半开非计数失败→退回原开断窗防困死;closed 计数失败 consec 累计,达阈→opened);`pushEvent` events 环≤20;`breakerSnapshot` 五员全列。
- 有态壳 `mkBreaker({file,env,round,ledgerFile,knobs,log})`:态=DOCS_ROOT/ops/breaker.json,tmp+renameSync 原子写(_ops_store 判例);每操作重读文件(跨轮跨壳同文件为真源);转移事件经 lib.sh `ledger_append` 追台账行(flock 同锁域,写败 log 不抛=appendRefusalTrace 判例);旋钮 `readBreakerKnobs` 字面点形读(扫描面即契约面,A 的表驱动回退教训),缺省 3/21600,非负有限否则 `{usage:true}`,threshold=0=禁用。
2. **ops/agent/tools.mjs**:唯一接线点。constructor `mkBreaker({file:opts.breakerFile, env:opts.env, round, ledgerFile:opts.breakerLedgerFile})`;beforeToolCall 守卫序 **dup→breaker→cap**(自决#1),开断拦=结构化 `code=channel_open` 信封(带剩窗秒/探活在飞+下一步合法动作=改用非通道工具或升级人裁;勿轮内重试勿绕行),零 spawn;`finish()` 从结构化信封结算(仅通道工具、`structured.ok` 布尔面)——信封出口单源,注册表/测量/发现面零逐点撒。
3. **ops/agent/error-codes.mjs**:ERROR_CODES 13→14 加 `channel_open`。
4. **ops/agent/agent.mjs**:SPAWN_CONTRACT_ENV 追 OPS_BREAKER_THRESHOLD(default 3)/OPS_BREAKER_COOLDOWN_S(default 21600),phase=call-time。
5. **ops/agent/pipeline.mjs**:mkCtx 轮始校验 breaker 旋钮(budget 判例);恢复重建 ctx 同步。
6. **ops/agent/pipeline/steps.mjs**:CLOSE 快照 `readings.breaker`(mkBreaker 只读 snapshot:五通道态面+生效旋钮;**观察不裁决,G_CLOSE 不加对拍**=自决#3)。
7. 测试:selftest-t4 +5 例(闭集+旋钮/parse 纯核/verdict+grantProbe/applyResult/有态壳跨壳持久+探活+恢复+坏文件 fail-closed+台账留痕/宿主接线拦+非通道放行+跨轮成功清零;全局 host 落 breakerFile TMP 隔离+breakerLedgerFile 台账隔离);selftest-contract(14 词断言/名集断言/SRCS+聚合扩 tools/breaker.mjs);selftest-pipeline B-快照例(09-budget.json readings.breaker 在+轮后无 ops/breaker.json=快照零写)。
8. 典章(见下 commit 41a0c870)+CHANGELOG 交付B 双语条(含部署注记:breaker.json 由首个计数通道结果自动创建,快照/verdict 面永不写)。

## commit 链

- 68a36a09 wip: #199 交付B 开工(占位)
- 0dc92505 交付B 主体(breaker.mjs+接线+ERROR_CODES 14+旋钮表+快照+三面测试)
- 41a0c870 典章收口(A+B 同批:STANDARD P15/P16 翻已有/D-5 措辞+挂点/建议区两行删/DESIGN:74 翻正/GLOSSARY 铸词/CHANGELOG)
- (本报告 commit)

## 各门数字(红期→绿)

| 门 | 基线(A 后) | 红期 | 终态 |
|---|---|---|---|
| selftest-t4 | 58/0 | 55 pass 后模块装载崩(breaker.mjs 缺,exit 1) | **63/0** |
| selftest-contract | 18/0 | 17/1(14 词闭集断言) | **18/0** |
| selftest-pipeline | 77/0 | 77/1(readings.breaker 缺) | **78/0** |
| golden | 9/0 | —(结构断言面,快照增字段不破) | **9/0** |
| standard-check | 48 挂点30 | —(典章未动期不变) | **47/0 挂点31 建议10 原语22(已有12/半缺7/缺3)** |
| selftest.sh | 115/0 | — | **115/0** |
| backend pytest | 未触(backend/frontend 零改动) | — | 未跑(无触面) |

红期采集法:git stash 临时回退实现侧(留测试)真跑三红,再 pop 复绿——红是真红非纸面。

## 自决(spec 未钉处,全部留档)

1. beforeToolCall 守卫序 dup→breaker→cap:A4 注释钉 dup 先于每工具帽;熔断属通道级前置闸,插中间(先拦重复省预算计数,再拦通道级持久证据)。
2. threshold=0=禁用熔断(同 OPS_PIPELINE_DUP_CALL_LIMIT=0 停用判例);非负有限校验沿 mkCtx 判例 exit 2 用法错。
3. G_CLOSE 不加 breaker 对拍:快照是观察面,熔断无「帽可超」语义,回声哨只拍有帽读数(对拍死表项红面代价不值)。
4. 半开非计数失败退回**原**开断窗(非新窗):探活烧掉但证据非部署/账户级,下一窗可再探;新窗会半开死循环困死通道。
5. 探活名额持久化在 grantProbe 落盘时刻(同步):探活在飞中崩溃,重启见 half_open 即知名额已耗,不双探。
6. 计数回喂取 finish() 结构化信封码(=classifyChannelError 分类出口),非 classify 调用点逐处撒——同一数据更单源;spec「调用点回喂」意图=信封码喂计数,实现形如此。
7. pipeline 面不接线:microprobe 三工具(probe_head/reprobe_get/reprobe_ua)不在五通道闭集,通道工具只活 legacy ToolHost 面;spec「两面自动同享」按闭集合同实现=无通道工具面天然无需接线(发现,非偏离)。
8. 台账留痕=lib.sh ledger_append 同锁域行+文件内 events 环(≤20);RETRO 面留痕=09-budget.json readings.breaker 快照(轮终观测件)。spec 只说「台账/RETRO 留痕」,以此两件+快照兑现。
9. GLOSSARY 铸词面:任务书钉两词(预算四界/跨轮熔断一行式)已铸;spec 典章节另列「双点执法/调用哈希/半开探活/通道开断」候选——按任务书收窄,后四者作词条内行文不独立铸词(终审可扩)。
10. 典章 A 行(DESIGN:74 翻正/P15 行注记/预扣结算词条陈句)由 B 批代收:A 的典章面按任务书「A 留给你的」整批移交本批。

## 遗留

- 半开探活=「下一次真实调用即探活」,无独立合成健康检查 spawn(spec 未钉合成探活;零白烧哲学下取真调用形)。
- events 环上限 20(状态文件尺寸上界),溢出即弃最旧——不外发、不持门,完整留痕在台账行。
- 开断态翻转只在调用时评估(verdict 时点),无后台定时器翻转——无调用的通道冷却后首次调用才探活,属惰性语义(零常驻进程)。
- 生产 breaker.json 首现=首个计数通道失败时(成功 consec=0 零写);CHANGELOG 部署注记按此措辞,spec「首轮自动创建」按真实时点收窄。
Loading
Loading