audit: task-attempt ledger feeds real first-pass/defect/rework rates (gap 3)
- cloud/attempt_ledger.py: separate task_attempts table (not tasks columns) with per-attempt rows, MAX+1 attempt_no, append-only intent; interrupted rows kept but never counted; is_defect is explicit, never inferred from failure; first defect category wins; no-ledger tasks stay unknown (None), never backfilled. SQLite DDL is CREATE TABLE IF NOT EXISTS (idempotent); PG_DDL is the verbatim manual step for production Postgres, kept out of POSTGRES_SCHEMA on purpose (migrations coverage untouched). - cloud/server.py GET /metrics-report: aggregates the ledger into compute_metrics records; missing ledger table degrades to unknown rates, not an error. Cost dual-column code untouched. - cloud/metrics.py: docstring only (ledger is now the source); compute_metrics logic and all #238 semantics unchanged. - Tests: 16 ledger tests (store/aggregate/metrics/PG adapter evidence) + 3 endpoint tests (real rates, old task beside ledger task, interrupted status non-terminal).
This commit is contained in:
1 parent
238ebbdbd2
commit
0db51f8145
6 files changed
+639
-22
No files matched your search
@@ -40,10 +40,55 @@ workflow——第 2 轨拥有 lint/类型/安扫,本轨不碰。
|
||||
`priced_usd_micros_partial` 出现——无价永不记 0、永不折进总额。
|
||||
- 未知率回 `None` + `*_known: false`,绝不报 0。
|
||||
|
||||
当前诚实边界(端点实测):tasks 表无 attempts/defects 列,端点
|
||||
传 `None`,首过/缺陷/返工率恒为 `None`;金任务集未经人工审定,
|
||||
报告恒为 `pending_human_approval`、`decision_ready: false`。接真实
|
||||
输入需两项前置(见待审定清单),本轨不编造。
|
||||
当前诚实边界(端点实测,审计加固补缺口第 3 项之后):tasks 表
|
||||
仍无 attempts/defects 列——台账改为独立表
|
||||
`task_attempts`(`cloud/attempt_ledger.py`),不改主表结构。
|
||||
端点 `GET /metrics-report` 聚合台账后传给 `compute_metrics`:
|
||||
有台账行的任务算出真实首过/缺陷/返工率;无台账行的老任务
|
||||
仍回 `None` + `*_known: false`,绝不被算成首过或无缺陷;
|
||||
台账表尚不存在(老库、或生产 PG 未手动执行 `PG_DDL`)时
|
||||
端点与无台账行同等处理,不报错。金任务集未经人工审定,
|
||||
报告恒为 `pending_human_approval`、`decision_ready: false`。
|
||||
|
||||
## 任务尝试台账(审计加固补缺口第 3 项,选型与口径)
|
||||
|
||||
选型:独立台账表,不改主表。列方案查询简单(一行一任务、
|
||||
无关联),但把每次尝试的历史压成两个计数器——哪次尝试失败、
|
||||
属哪类缺陷、顺序如何,事后无法恢复;且在生产 Postgres 上拓
|
||||
宽高频 `tasks` 表比重建一张空表更重。台账表多一次聚合查询,
|
||||
换来完整尝试历史与不碰主表的迁移,取舍写在
|
||||
`cloud/attempt_ledger.py` 模块 docstring 里。
|
||||
|
||||
表 `task_attempts(task_id, attempt_no, outcome, is_defect,
|
||||
defect_category, created_at)`,主键 `(task_id, attempt_no)`,
|
||||
`attempt_no` 按任务 `MAX + 1` 递增、只追加不改写。口径:
|
||||
|
||||
- `outcome` ∈ success / failure / interrupted;`interrupted`
|
||||
行只留档,不计入 attempts 也不计入 defects(平台中断自动
|
||||
重跑是平台事件,不是 agent 失败;只有中断行的任务在聚合
|
||||
里直接缺席,仍回未知而非 0)。
|
||||
- `is_defect` 由记录方显式判定,绝不从 `failure` 自动推导
|
||||
(失败重试未必是缺陷轮);`defect_category` 须配
|
||||
`is_defect=True`,中断行永不能是缺陷,违例写时即
|
||||
`ValueError`,不存歧义数据。任务的单类别标签取首个缺陷
|
||||
行的类别(attempt_no 顺序,先到先得,确定性)。
|
||||
- 迁移幂等:SQLite 侧 `CREATE TABLE IF NOT EXISTS`,重跑
|
||||
不动已有行;Postgres 侧 `PG_DDL`(与 SQLite DDL 同文,只用
|
||||
Postgres 合法类型与复合主键、无自增/identity 列,故无需
|
||||
序列处理)**须在生产 PG 上手动执行并验证**(`\d
|
||||
task_attempts` 或 information_schema 等价查询),且有意不
|
||||
进 `POSTGRES_SCHEMA`(不静默拓宽迁移覆盖集);手动步骤
|
||||
未做之前,Postgres 端点只会回未知率,不会报错。本机无
|
||||
PG,真实 PG 验证未做;PG 证据目前只有适配层级别:`?` 占位
|
||||
经 `cloud.db` 适配翻译为 `%s`、DDL 无需序列处理(测试
|
||||
`TestPostgresAdapterEvidence` 钉住)。
|
||||
- 未做项(有意不做,原因见模块 docstring):生命周期写
|
||||
入钩子未接——worker 重试/续跑循环里哪一次算一次尝试、谁
|
||||
判定 `is_defect`,接错会把平台自动续跑算成尝试、把瞬时
|
||||
重试算成缺陷,正好违反本轨钉住的规则;在此之前台账只
|
||||
经显式 `record_attempt` 调用填充,生产率在写钩子落地前
|
||||
保持诚实未知,不自动填数。读端点不建表(只读端点不改
|
||||
schema),建表只发生在写路径。
|
||||
|
||||
## 回流与审计标准迭代(可测试规则,非口号)
|
||||
|
||||
@@ -93,3 +138,7 @@ workflow——第 2 轨拥有 lint/类型/安扫,本轨不碰。
|
||||
|
||||
待人工项(单独列):金任务集审定清单的四项人工确认;抽查 seed
|
||||
的记录与保管;生产抽查比例拍板(默认值 0.10/0.50 只是测试初值)。
|
||||
台账待人工项(补缺口第 3 项之后):生产 PG 上手动执行
|
||||
`task_attempts` 的 `PG_DDL` 并验证;生命周期写入钩子拍板——
|
||||
哪次执行算一次尝试、谁判定 `is_defect`(在拍板前台账只经
|
||||
显式调用填充,生产率保持未知)。
|
||||
Reference in new issue
Block a user