code-to10 v5 rebase follow-up: keep main #275 resident working on rebased tree

- restore _audit_row in cloud/automations.py as a thin wrapper over
  cloud.auth.audit_on_conn (legacy row + ledger entry pair,
  user_id system, best-effort self-commit preserved). The stack's
  gap-4 option A deleted the direct writer; main #275 resident.py
  imports _audit_row, so the bare rebase broke server import.
  No direct audit_log INSERT is reintroduced, so the #250
  no-bypass scan stays green.
- conformance accounting 238/144 -> 243/149: main #275 added 5
  resident methods that legitimately stay in server.py; moved
  count stays 94, no duplicates.
- directional: resident x3, audit chain, conformance, automations
  x3 suites, 51 tests OK
This commit is contained in:
host committed 2026-11-03 02:49:26 +00:00
1 parent 6bceed484c
commit 34a19ab9e2
2 files changed
+32 -7

No files matched your search

+25 -2
View File
@@ -610,14 +610,37 @@ def _is_integrity_error(exc):
只有这类错误值得在事务边界重试整段;其它错误重试无用,
必须立即回滚抛错,不能被重试掩盖成“锁/冲突问题”。
旧 _audit_row 已删除:本模块不再有任何 audit_log 直写,
审计只走 _audit_on_conn(见模块文档)。
本模块不直写 audit_log:审计只走 _audit_on_conn(见模块文档);
下面的 _audit_row 仅为兼容包装(供 main #275 resident.py),
本身仍走 _audit_on_conn,不含 audit_log INSERT。
"""
if isinstance(exc, sqlite3.IntegrityError):
return True
return type(exc).__name__ == "PostgresIntegrityError"
def _audit_row(conn, project_id, action, detail, now):
"""兼容包装:供 main #275 resident.py 的审计调用。
本函数不直写 audit_log(#250 断言只允许 auth.py 出现
audit_log INSERT):经 cloud.auth.audit_on_conn 写
audit_log 行 + audit_ledger 链条目同一对,user_id 仍为
"system"、created_at 用调用方给的 now。保留 main 旧版的
best-effort 自提交语义:写对失败时回滚后吞掉,不影响
resident 轮询本身;调用方已 commit 的业务行不受影响
(审计对写是独立的后续写)。
"""
try:
_audit_on_conn(conn, "system", project_id, action, detail,
created_at=now)
conn.commit()
except Exception:
try:
conn.rollback()
except Exception:
pass
def run_due_automation(conn, automation_id, now=None):
"""云端自动化执行器的唯一入口:抢单 -> 配额门 -> 建任务 -> 记产出。
@@ -9,8 +9,10 @@ Pins the split contract so a future violation fails CI:
as #238 arch_conformance.scan_imports);
- server.py re-exports the moved shared helpers as identical objects,
so `from cloud.server import _task_to_dict` keeps working;
- handler method accounting: 238 total, 144 left in server.py itself,
94 in mixins, no name defined twice.
- handler method accounting: 243 total, 149 left in server.py itself,
94 in mixins, no name defined twice. (v5 rebase: main #275 added
5 resident methods that legitimately stay in server.py, so the
stack's 238/144 becomes 243/149; moved count stays 94.)
Only the standard library; no real model, no network, no secrets.
"""
@@ -138,7 +140,7 @@ class TestReexports(unittest.TestCase):
class TestMethodAccounting(unittest.TestCase):
def test_total_238_no_duplicates(self):
def test_total_243_no_duplicates(self):
seen = {}
dups = []
classes = [CloudControlPlaneHandler]
@@ -153,9 +155,9 @@ class TestMethodAccounting(unittest.TestCase):
dups.append((seen[name], cls.__name__, name))
seen[name] = cls.__name__
self.assertEqual(dups, [])
self.assertEqual(total, 238)
self.assertEqual(total, 243)
self.assertEqual(len(_own_methods(CloudControlPlaneHandler)),
238 - 94)
243 - 94)
if __name__ == "__main__":