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)
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.
64 lines
2.3 KiB
Python
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")
|