- cloud/audit_scorecard.py: pure stdlib scorer, structured evidence in, 7 dimension scores (0-10, 1 decimal), basis, missing/untested items, overall pass only when all 7 >= 9; unknown -> None, never 0/10/estimated; fixture/viewport/code-review evidence -> untested, never pass; thresholds all test_default_unapproved, user_approved only on explicit input. - server.py: GET /audit-scorecard read-only, same auth/member scope as /metrics, no DB writes, no ledger writes, no pushback/reaudit triggers; on main base it honestly reports unknown/not-enforced, overall not_pass. - docs/audit-scorecard.md: spec, formulas, threshold table, unknown handling, overall rule, 10-to-7 merge mapping, relations to #238 metrics-report, #244 sampling, #260/#261 loop, and a system-computed example (current state, overall not_pass) clearly separated from the previous judgement estimates. - tests: 12 new items pin all-pass, one-below-nine fails, average 9.1 with one 4 still fails, unknown None, fixture untested, conditional not a pass, thresholds unapproved, endpoint 401/200 read-only. - suites: cloud 1442 OK (skipped 4), top-level 105 OK, deploy 39 OK.
166 lines
9.4 KiB
Markdown
166 lines
9.4 KiB
Markdown
# 7 维项目级审计评分卡规格
|
||
|
||
本文件是评分卡的规格文档,也是唯一权威的计分说明。
|
||
代码在 `cloud/audit_scorecard.py`,只读端点在 `server.py` 的
|
||
`GET /audit-scorecard`,测试在 `cloud/tests/test_audit_scorecard.py`。
|
||
三处不一致时,以“总体规则钉死”那一节为准,先改文档再改代码。
|
||
|
||
## 总体规则(钉死)
|
||
|
||
- 7 维全部 >= 9.0 才算达标(overall="pass")。
|
||
- 任一维 < 9.0,总体就不达标(overall="not_pass")。
|
||
- 平均分(average_score)只作参考信息,绝不能作为达标依据。
|
||
反例已钉进测试:6 维 10 分、1 维 4 分,平均 9.1 分,总体仍是不达标。
|
||
- 未知维记 None:数据源缺失、未知、未验证时,该维分数记为 None,
|
||
不记 0、不记 10、不估算,总体直接不达标,并列出缺失项。
|
||
平均分只对已知维求平均(未知维不计入分母),所以平均分
|
||
绝不能被读成“7 维总分”。
|
||
- 未实测维记未实测:调用方传入“夹具模拟”“视口替代”
|
||
“未编译端代码评审”“干跑”“估计”这类证据时,该项记为
|
||
untested_items,而不是“通过”;若某维的关键证据全部是未实测,
|
||
该维记为 None。
|
||
- 阈值默认值一律标注 test_default_unapproved(测试默认值、未拍板)。
|
||
生产阈值须用户拍板后,由调用方显式传入
|
||
thresholds(含 source="user_approved")才能替换默认值。
|
||
本模块绝不把测试初值写成生产值。
|
||
|
||
## 7 维定义与数据源
|
||
|
||
1. 交付质量(delivery_quality)
|
||
数据源:#238 metrics + #249/#255 台账。
|
||
输入:first_pass_rate、defect_rate、rework_rate,
|
||
first_pass_known、defect_known、rework_known、attempts_present。
|
||
计算:三个率各自按“floor -> 5 分、9 分线 -> 9 分、10 分线 -> 10 分”
|
||
分段线性算子分,维分数取三者最小值(任一率不达标,维就不达标)。
|
||
|
||
2. 门禁与审计有效性(gate_audit)
|
||
数据源:#240 硬门禁、#244 推回、#247 接线、#260/#261 自动循环。
|
||
输入:hard_gate_enforced、gate_items_passed/total、
|
||
merge_blocked_verified、loop_end_to_end_verified、
|
||
sampling_misjudgment_rate、audit_verdict。
|
||
计算:门禁项通过率(99% -> 9 分、100% -> 10 分)与抽查判错率
|
||
(越低越好)取最小值;hard_gate_enforced=False 已知未强制时
|
||
分数封顶 4.0;合并阻塞或自动循环端到端未真实验证时封顶 4.0;
|
||
audit_verdict="conditional" 记无效证据,不算通过。
|
||
|
||
3. 架构与契约一致性(arch_contract)
|
||
数据源:#238 arch_conformance。
|
||
输入:contract_frozen、arch_violations、directory_violations、
|
||
import_violations、stack_changed_without_approval。
|
||
计算:违规总数为 0 且合同已冻结且技术栈未擅自变更时 10 分;
|
||
任一违规时封顶 5.0;未冻结或擅自换栈时封顶 4.0;
|
||
任一违规数未知时记 None。
|
||
|
||
4. 测试与验证覆盖(test_coverage)
|
||
数据源:G5 QA 矩阵、agent 专属六项、#253/#251 覆盖率与
|
||
lint/mypy/bandit。
|
||
输入:prd_coverage_rate、cross_matrix_coverage_rate、coverage_pct、
|
||
cross_matrix_kind、real_pg、real_service、agent_six_complete、
|
||
lint_items、mypy_items、bandit_high。
|
||
计算:PRD 覆盖率、跨端矩阵覆盖率、代码覆盖率取最小值;
|
||
agent 六项缺项时封顶 4.0;静态检查总数 >0 时封顶 8.0;
|
||
跨端矩阵不是 real、或真实 PG、真实服务未验证时,该维记 None。
|
||
|
||
5. 安全与账本可信(security_ledger)
|
||
数据源:#241 哈希链、#250 旁路行上链、#256 shell 白名单、
|
||
分支保护状态。
|
||
输入:ledger_verify_ok、ledger_coverage_rate、
|
||
shell_whitelist_pass_rate、branch_protection、anchor_check_recent。
|
||
计算:账本覆盖率取分;分支保护 unknown/缺失时记 None,
|
||
unprotected 已知未保护时封顶 4.0,账本校验未通过时封顶 4.0,
|
||
锚点定期校验未落地时封顶 8.0。
|
||
|
||
6. 成本与配额可观测(cost_quota)
|
||
数据源:#212 双列成本、#249 台账、#255 钩子。
|
||
输入:cost_records_complete、unpriced_as_zero、per_creator_present、
|
||
quota_cutoff_verified。
|
||
计算:成本记录不完整(turns/llm_requests/usd_micros 缺失)时
|
||
记 None;无价记成 0/免费时 0.0 分;配额硬切断未真实验证时
|
||
封顶 4.0;按创建者成本未落地时封顶 8.0;四项全齐时 10 分。
|
||
|
||
7. 生产运维与规模(ops_scale)
|
||
数据源:主机健康、4 个 unit、CI 状态、部署与回滚记录、
|
||
并行规模测试。
|
||
输入:ci_green_rate、deploy_success_rate、rollback_drill_done、
|
||
ha_status、parallel_scale_proven、parallel_scale_accepted_alternative。
|
||
计算:CI 变绿率、部署成功率取最小值;回滚演练未真实跑过时
|
||
封顶 4.0;单主机且未接受风险时封顶 5.0;并行规模按
|
||
proven/target * 10 算分(40 人满分,18 人约 4.5 分);
|
||
CI 变绿率未知或并行规模未知(且无已接受替代线)时记 None。
|
||
|
||
## 阈值表(默认值,全部未拍板)
|
||
|
||
| 阈值 | 默认值 | 来源 |
|
||
|---|---|---|
|
||
| defect_rate 9 分线 / 10 分线 / floor | 0.05 / 0.02 / 0.20 | 测试默认值、未拍板 |
|
||
| first_pass 9 分线 / 10 分线 / floor | 0.90 / 0.95 / 0.50 | 测试默认值、未拍板 |
|
||
| rework_rate 9 分线 / 10 分线 / floor | 0.10 / 0.05 / 0.50 | 测试默认值、未拍板 |
|
||
| overturn_rate floor | 0.30 | 测试默认值、未拍板 |
|
||
| coverage 9 分线 / 10 分线 / floor | 0.85 / 0.90 / 0.75 | 测试默认值、未拍板 |
|
||
| sampling 普通 / 关键 | 0.10 / 0.50 | 测试默认值、未拍板 |
|
||
| parallel_scale_target | 40 | 测试默认值、未拍板 |
|
||
|
||
注意:floor 不是达标线。floor 是分数进入 0-5 区间的参考点,
|
||
达标线永远是 9 分线。把 floor 读成达标线是错的。
|
||
|
||
## 与已有机制的关系(本评分卡不改它们)
|
||
|
||
- #238 metrics-report:评分卡的交付质量维复用它的指标口径,
|
||
但 metrics-report 本身不是评分卡;它的 evaluate_feedback
|
||
auto_apply 保持 False,评分卡不自动改标准。
|
||
- #244 抽查:评分卡的门禁维复用它的抽查口径(必抽、随机比例、
|
||
纠错),但评分卡不重新做抽查,只接受抽查结果作为证据。
|
||
- #260/#261 自动循环:评分卡的门禁维复用它的端到端验证
|
||
(审计 fail -> 修复子任务 -> 完整重审 -> 解封),但评分卡
|
||
不触发推回或重审;端点本身只读。
|
||
- #247 纠正语义:纠正为 pass 本身不解封,评分卡不设特例。
|
||
- #241 账本:评分卡只接受账本校验结果作为证据,不写链、不改链头。
|
||
|
||
## 10 维到 7 维的合并映射
|
||
|
||
- 流程完整性并入门禁与审计有效性:G0-G8 最终靠门禁和重审证明。
|
||
- 自动化程度并入门禁与审计有效性 + 生产运维与规模:
|
||
自动化的证据就是自动循环是否真实跑通、真实 App 是否安装。
|
||
- 文档与技能并入架构与契约一致性:
|
||
技能文本、附录溯源、移植规则最终都是契约一致性的一部分。
|
||
- 其余 7 维与上一轮 10 维一一对应,不再展开。
|
||
|
||
## 只读端点
|
||
|
||
`GET /audit-scorecard`,与 /metrics 同款认证与成员范围
|
||
(任意项目成员即可读,不要求 owner),但本端点不统计任何
|
||
项目数据、不写库、不写账本、不改链头、不触发推回或重审。
|
||
主基底(main)上没有存放结构化评分证据的表(metrics-report、
|
||
台账、账本、门禁模块都在未合并的 PR 分支上),所以本端点
|
||
在主基底上返回的只能是“全部未知/已知未强制”的诚实状态,
|
||
总体必然是不达标;调用方要拿到真实分数,必须显式把结构化
|
||
证据传给 `cloud/audit_scorecard.py` 的 `build_scorecard()`,
|
||
端点本身绝不从测试文件、摘要文档、PR 描述里拼凑分数。
|
||
|
||
## 示例评分卡(系统算出来的,不是上一轮判断分)
|
||
|
||
下面是 `example_scorecard_current_state()` 用当前真实状态证据
|
||
跑出来的系统输出,证据口径:生产仍跑 v0.2、main 仍 aebc623、
|
||
CI 账单模式、#238/#240/#244/#241/#247/#249/#253/#255/#256/
|
||
#258/#259/#260/#261 全部只到 PR OPEN。凡是只到 PR、未合并部署、
|
||
未真实验证的,在这里都记为未知或已知未强制,不估算。
|
||
|
||
- 交付质量:None(未知,台账无行、三个率都未知)
|
||
- 门禁与审计有效性:4.0(已知未强制,record 模式)
|
||
- 架构与契约一致性:None(未知,违规数与冻结状态都未知)
|
||
- 测试与验证覆盖:None(未知,PRD 与跨端覆盖率缺失,
|
||
跨端矩阵是视口替代、真实 PG 与真实服务未验证)
|
||
- 安全与账本可信:None(未知,账本校验与覆盖率未知,
|
||
分支保护 unknown)
|
||
- 成本与配额可观测:None(未知,成本记录不完整)
|
||
- 生产运维与规模:None(未知,CI 变绿率未知)
|
||
- 平均分(仅已知维平均,参考信息):4.0
|
||
- 总体结论:不达标(not_pass)
|
||
|
||
上一轮十维估计分(流程 8、自动化 5、门禁审计代码 8/生产实效 4、
|
||
代码架构 6.5、测试 6、生产运维 5、安全 5.5、成本 6、规模 4、
|
||
文档技能 7.5)是上一轮的判断分,不是系统算出来的分数,
|
||
不能写进示例评分卡的分数栏,只能作为对照表放在这里,
|
||
且示例总体结论必须是不达标——因为门禁审计生产实效、测试、
|
||
运维规模等维都远低于 9 分。
|