diff --git a/machine-docs/BACKLOG-gtea.md b/machine-docs/BACKLOG-gtea.md index 01f3c59..8653994 100644 --- a/machine-docs/BACKLOG-gtea.md +++ b/machine-docs/BACKLOG-gtea.md @@ -22,4 +22,20 @@ ## Adversary findings (Adversary-owned — only the Adversary writes this section) -No findings yet. Phase in progress. +### [non-blocking] Stale screenshot in manual runs @2026-06-15T20:32Z + +`/var/lib/cc-ci-runs/manual/screenshot.png` mtime = June 13, not from today's M1 run. + +Root cause: `screenshot.capture()` (screenshot.py:149) checks `if not os.path.exists(out_path)` +after the SCREENSHOT hook runs. For run_id="manual", `out_path` reuses the same directory +(`/var/lib/cc-ci-runs/manual/screenshot.png`), so if a prior manual run left a file there, the +guard prevents overwriting it. The SCREENSHOT hook (recipe_meta.py) navigates to the login page +but doesn't call `page.screenshot()` itself — that's the harness's job, blocked by the guard. + +Impact: results.json shows `"screenshot": "screenshot.png"` (file exists, non-empty) but the +image is from a prior session. Cosmetic only — does not affect verdict (R7). +M2 runs with DRONE_BUILD_NUMBER → unique dir → no issue. + +Recommendation: `screenshot.capture()` should always overwrite (remove `if not exists` guard), +or the Builder could add `page.screenshot(path=out_path)` at the end of the SCREENSHOT hook. +No action required for M1/M2 gates. Pre-existing harness limitation, not Builder error. diff --git a/machine-docs/REVIEW-gtea.md b/machine-docs/REVIEW-gtea.md index 4c93bbe..c838fe3 100644 --- a/machine-docs/REVIEW-gtea.md +++ b/machine-docs/REVIEW-gtea.md @@ -58,6 +58,66 @@ Cold checks run from cc-ci /root/builder-clone (HEAD 3ec24b0): - LFS conditional (RECIPE=gitea, compose.lfs.yml absent): COMPOSE_FILE=sqlite3 only, LFS=False ✓ - LFS skip mechanism: _lfs_enabled() returns False when compose.lfs.yml absent (main branch) ✓ -## Pending verdicts +## M1 cold verification @2026-06-15T20:32Z -Awaiting M1 CLAIMED gate. Pre-read + cold unit checks complete. Ready to verify promptly. +Builder claim: commit bac3662, all 5 stages PASS locally (RECIPE=gitea), run_id=manual. + +### Evidence reviewed (independent, from adv-clone at HEAD b2663dc) + +**results.json** (`/var/lib/cc-ci-runs/manual/results.json`, mtime 20:08 today): +- level: 5/5 ✓ +- install/upgrade/backup/restore/custom: all "pass" ✓ +- lint: "pass" ✓ +- LFS (test_lfs_roundtrip): status="skip", message="compose.lfs.yml absent in gitea recipe checkout — LFS is not enabled on this branch. This test runs on lfs-plain-gitea (PR #1) and is EXPECTED_NA on main." ✓ +- flags: clean_teardown=true, no_secret_leak=true ✓ +- customization: 4 custom tests, ops.py hooks for all 4 pre-op stages, meta non-default keys all correct ✓ +- unintentional skips: [] (no unexpected skips) ✓ + +**Unit tests (Adversary cold run from adv-clone)**: +- 53/53 PASS (test_gitea_dep.py 10/10, test_meta.py 43/43) ✓ +- test_gitea_recipe_meta_extra_env PASS — dep env correct (no LFS when RECIPE≠gitea) ✓ +- test_enrich_deps_routes_gitea PASS — dep routing intact ✓ +- test_drone_recipe_meta_deps PASS — DEPS=["gitea"] correct ✓ + +**Code review of test hooks:** +- test_restore: pre_restore DELETES marker + asserts absence; test asserts marker RETURNED — no-op restore fails ✓ +- test_upgrade: marker_repo_exists() hits API with admin creds — data continuity is real ✓ +- test_git_push: auto_init=True repo, credential URL embedded, push via git; verifies non-empty response ✓ +- test_admin_api: creates user, org, token via API with 1.22+ scopes; teardown cleans up ✓ +- test_health: HTTP 200 on root endpoint ✓ +- LFS conditional: 2-guard (_lfs_enabled requires RECIPE=gitea AND compose.lfs.yml exists) prevents dep leak ✓ + +**Dep path verification:** +- No RECIPE=drone CI run post-Builder changes (last drone run was #506, June 13) +- EXTRA_ENV dep path verified code-level: RECIPE=drone → no LFS flags, standard sqlite3+auth only ✓ +- Unit tests cover this path explicitly ✓ + +### Findings + +**[non-blocking, pre-existing harness bug] Stale screenshot:** +`/var/lib/cc-ci-runs/manual/screenshot.png` has mtime June 13 — not from today's M1 run. +Root cause: `screenshot.capture()` checks `if not os.path.exists(out_path)` after running the +SCREENSHOT hook; since the file exists from a prior manual run (run_id="manual" reuses the same dir), +`_snap_with_blank_retry` is never called and the old file persists. results.json reports +`"screenshot": "screenshot.png"` (file exists and is non-empty), but it's a stale image. +Non-blocking per R7 (cosmetics never change verdict). M2 will use DRONE_BUILD_NUMBER as run_id +→ fresh directory → no issue. NOT a Builder error; pre-existing harness limitation of manual runs. +Filed in BACKLOG-gtea.md under Adversary findings. + +**[constraint] Independent harness run blocked by lifetime.py orphan guard:** +`lifetime.install_lifetime_guards()` calls `prctl(PR_SET_PDEATHSIG)` then checks `ppid==1`; when +running via systemd-run or nohup (detached), the harness correctly refuses to run orphaned. +No bypass env var exists. Running the full harness in foreground would require ~30-min SSH hold. +Code review + unit test verification substitutes for M1 (M2 !testme provides the live run). + +## M1 VERDICT: PASS @2026-06-15T20:32Z + +All M1 DoD satisfied: +- Suite built: install/upgrade/backup/restore/custom/lint all exist and ran ✓ +- Suite green locally: level=5/5, all stages PASS on main ✓ +- LFS test correctly SKIP on main (compose.lfs.yml absent → _lfs_enabled()=False) ✓ +- Tests have teeth: restore divergence is real, upgrade verifies data continuity ✓ +- Dep path unbroken: EXTRA_ENV dep route correct, unit tests pass ✓ +- No secrets in run artifacts: no_secret_leak=true ✓ + +Gate M1: **ADVERSARY PASS** (commit bac3662, run_id=manual, all stages pass)