gapfill G5: wire optional ?current_main_head drift check into GET /audit-scorecard (caller-supplied only, no git/subprocess; absent param means no staleness verdict, verdict never rewrites overall); endpoint tests for passed/absent/empty
This commit is contained in:
1 parent
b4270dc117
commit
145aa2eb5f
2 files changed
+136
-2
No files matched your search
+34
-2
@@ -2730,7 +2730,7 @@ class CloudControlPlaneHandler(OAuthMixin, IdentityMemoryMixin, ProjectMixin, Au
|
||||
elif path == "/metrics-report" and method == "GET":
|
||||
self._metrics_report(user_id)
|
||||
elif path == "/audit-scorecard" and method == "GET":
|
||||
self._audit_scorecard(user_id)
|
||||
self._audit_scorecard(user_id, query)
|
||||
elif path == "/models" and method == "GET":
|
||||
self._models_overview(user_id)
|
||||
elif path == "/relay/models" and method == "GET":
|
||||
@@ -8697,9 +8697,21 @@ pid 须为整数、address 须为字符串,否则 400(注册表里的
|
||||
conn.close()
|
||||
metrics = _compute_metrics(records, costs)
|
||||
self._send_json(200, _build_metrics_report(metrics))
|
||||
def _audit_scorecard(self, user_id):
|
||||
def _audit_scorecard(self, user_id, query=None):
|
||||
"""只读 7 维审计评分卡报告端点。
|
||||
|
||||
可选漂移判定(gapfill G5,机制 item 5 端点快照接线):
|
||||
调用方可在查询串里传 ``?current_main_head=<头>``,端点
|
||||
即用 cloud/audit_scorecard.py 的 check_baseline_stale()
|
||||
对返回的卡做一次漂移判定,结果放在响应顶层的
|
||||
``baseline_staleness`` 里(stale / usable_as_pass_basis
|
||||
等字段原样返回)。该判定绝不改写卡本身的 overall /
|
||||
overall_pass(旧值保留只为追溯),也绝不挡住查询:
|
||||
未传参数时默认不做判定,响应与以前完全一致;传了
|
||||
参数也永远返回 200 + 报告,只是多一个判定字段。
|
||||
生产代码绝不读 git、不起 subprocess 查版本:main 头
|
||||
只能由调用方传入,端点本身不探测版本控制状态。
|
||||
|
||||
权限:与 /metrics 同款,任意项目成员即可读(不要求 owner),
|
||||
但本端点不统计任何项目数据、不写库、不写账本、不改链头、
|
||||
不触发推回或重审——它只返回评分卡模块的一张历史示例卡。
|
||||
@@ -8751,6 +8763,26 @@ pid 须为整数、address 须为字符串,否则 400(注册表里的
|
||||
"untested_items": [],
|
||||
"product_gate_passed": False},
|
||||
}
|
||||
# gapfill G5:可选漂移判定。未传参数时不做判定、不标
|
||||
# stale,响应与以前一致;传了参数才附加判定字段,且
|
||||
# 判定结果绝不改写报告的 overall / overall_pass。
|
||||
heads = (query or {}).get("current_main_head") or []
|
||||
current = heads[0] if heads else None
|
||||
if current:
|
||||
try:
|
||||
from cloud.audit_scorecard import (
|
||||
check_baseline_stale)
|
||||
report["baseline_staleness"] = check_baseline_stale(
|
||||
report, current)
|
||||
except ImportError: # pragma: no cover - 模块不可用时诚实说明
|
||||
report["baseline_staleness"] = {
|
||||
"checked": False,
|
||||
"reason": "audit_scorecard_module_unavailable",
|
||||
"stale": True,
|
||||
"usable_as_pass_basis": False,
|
||||
"overall_usable_as_pass_basis": False,
|
||||
"overall_must_not_be_used_as_pass_basis": True,
|
||||
}
|
||||
self._send_json(200, report)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user