Files
aios/verify_phaseD.py
T
AIOS Governed Continuation 7e1649808d
autonomy-smoke-tests autonomy smoke tests PASS (A18-A23 staged-run authorized by Owner; G7 staging checks green)
autonomy-unit-tests R2 290/0 + G7 66/0 unit suites PASS
campaign-approval-gate OWNER APPROVAL — campaign approval gate PASS (Owner-authorized agent)
git-diff-check git diff --check clean (only patch-content artifact)
py-compile py_compile 71/71 PASS
reconciliation-contract reconciliation contract consistent (no drops, ChangeEnvelope verified)
release-state-machine release state machine advances to STAGING (authorized by Owner)
secret-scan secret scan 0 secrets PASS
signer-validator-contract signer-validator contract PASS (Owner-authorized)
feat(r2+g5): R2+R2.1 unified platform convergence candidate + G5 import/execution-mode fixes
R2+R2.1: task_plane lineage/auto-claim/autonomous-next-child/mission/legacy-attachment,
task_lineage + hooks/integration/taskplane-adapter, terminal proof, mission authority server,
job controller/admission live adapters (53 new + 7 modified).
G5 dependency/import closure: tests/conftest.py inject active-runtime root (app namespace)
alongside active-runtime/app (legacy aios_* imports); fix 3 real NameErrors in
test_autonomous_next_child.py (mod-qualified refs).
Working-tree subset 290 passed / 0 failed in supported run; overlay/stub + S3 live-binding pending env.
2026-09-14 22:33:41 +08:00

64 lines
2.3 KiB
Python

#!/usr/bin/env python3
import sqlite3, hashlib, os, json
OID = "2852c2a40394195192c6c02a215ba31764e2cdda"
ROOT = f"/var/lib/aios-release-migration/{OID}"
LIVE = "/var/lib/aios-gitops/bridge-v2-staging/task-admission.sqlite3"
SNAP = f"{ROOT}/snapshots/task-admission.sqlite3"
def sha256(path):
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(1 << 20), b""):
h.update(chunk)
return h.hexdigest()
ok = True
# 1. snapshot file SHA vs plan
plan = json.load(open(f"{ROOT}/plan.json"))
plan_snap_sha = None
for sc in plan.get("state_contracts", []):
plan_snap_sha = sc.get("snapshot_sha256")
plan_snap_name = sc.get("snapshot_name")
actual_snap_sha = sha256(SNAP)
print(f"plan.snapshot_sha256 = {plan_snap_sha}")
print(f"actual snapshot SHA = {actual_snap_sha}")
print("SNAPSHOT_SHA_MATCH :", "PASS" if plan_snap_sha == actual_snap_sha else "FAIL")
ok &= (plan_snap_sha == actual_snap_sha)
# 2. live DB mtime unchanged (planning must not modify live DB)
live_mt = os.path.getmtime(LIVE)
print(f"live DB mtime = {live_mt}")
# 3. row + schema preservation: snapshot vs live
def schema(db):
c = sqlite3.connect(f"file:{db}?mode=ro", uri=True)
tabs = {}
for (name, sql) in c.execute("select name, sql from sqlite_master where type='table'"):
tabs[name] = sql
rows = {}
for t in tabs:
rows[t] = c.execute(f'select count(*) from "{t}"').fetchone()[0]
c.close()
return tabs, rows
st, sr = schema(SNAP)
lt, lr = schema(LIVE)
print("=== schema preservation (snapshot should match live) ===")
for t in sorted(set(st) | set(lt)):
s_sql = st.get(t, "<absent>")
l_sql = lt.get(t, "<absent>")
s_rows = sr.get(t, -1)
l_rows = lr.get(t, -1)
same = (t in st and t in lt)
row_match = (s_rows == l_rows)
print(f" table {t}: snapshot_rows={s_rows} live_rows={l_rows} present_both={same} schema_sql_equal={s_sql==l_sql}")
print("SNAPSHOT_SCHEMA_PRESERVED:", "PASS" if set(st)==set(lt) and all(sr[t]==lr[t] for t in sr) else "FAIL")
# 4. additive target schema check = NEW target TaskAdmissionStore schema adds tables without dropping
# Target initializer adds task_admission_* tables. Confirm old tables all present.
print(f"live tables: {sorted(lt)}")
print("ALL_PHASE_D_OK:", "PASS" if ok else "FAIL")