feat: 7-dim project audit scorecard (all >=9 to pass, average never a pass criterion)

- 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.
This commit is contained in:
host committed 2026-11-03 02:49:25 +00:00
1 parent 3eac2a702e
commit b9466e556b
4 files changed
+941

No files matched your search

+28
View File
@@ -3042,6 +3042,8 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
self._metrics(user_id)
elif path == "/metrics-report" and method == "GET":
self._metrics_report(user_id)
elif path == "/audit-scorecard" and method == "GET":
self._audit_scorecard(user_id)
elif path == "/models" and method == "GET":
self._models_overview(user_id)
elif path == "/relay/models" and method == "GET":
@@ -10222,6 +10224,32 @@ pid 须为整数、address 须为字符串,否则 400(注册表里的
conn.close()
metrics = _compute_metrics(records, costs)
self._send_json(200, _build_metrics_report(metrics))
def _audit_scorecard(self, user_id):
"""只读 7 维审计评分卡报告端点。
权限:与 /metrics 同款,任意项目成员即可读(不要求 owner),
但本端点不统计任何项目数据、不写库、不写账本、不改链头、
不触发推回或重审——它只是把评分卡模块的当前状态报出来。
主基底(main)上没有存放结构化评分证据的表(metrics-report、
台账、账本、门禁模块都在未合并的 PR 分支上),所以本端点
在主基底上返回的只能是“全部未知/已知未强制”的诚实状态,
总体必然是不达标;调用方要拿到真实分数,必须显式把结构化
证据传给 cloud/audit_scorecard.py 的 build_scorecard(),
端点本身绝不从测试文件、摘要文档、PR 描述里拼凑分数。
"""
try:
from cloud.audit_scorecard import example_scorecard_current_state
report = example_scorecard_current_state()
except ImportError: # pragma: no cover - 导入失败时仍要诚实返回
report = {
"dimensions": [], "average_score": None,
"average_is_not_pass_criterion": True,
"overall": "not_pass", "overall_pass": False,
"missing_items": ["audit_scorecard_module_unavailable"],
"untested_items": [],
"thresholds_source": "test_default_unapproved",
}
self._send_json(200, report)
# -- OAuth(pre-auth,靠 state + secret,不走 X-API-Key)-----------
def _oauth_provider(self, path):