CIS490/tests
max 8d2d0d2e99 prune+receiver: preserve index ownership and add a backfill helper (closes #13)
Root cause of #13 (PUT 500s on first ship, retries return already-present):
my earlier prune-tool session ran as root and rewrote the live index via
os.replace(), which drops the original ownership/mode. The new file was
root:root and the cis490 service user couldn't append to it. Every fresh
PUT 500'd on _append_index after the tarball had already landed via
os.replace, so retries always saw "already-present" and never recovered
the missing index row.

Two fixes:

- tools/prune_episodes.py: snapshot the index's stat before the rename
  and restore uid/gid/mode after. Best-effort chown so non-root prune
  runs (where chown would EPERM) still succeed; non-root callers
  matched the original owner anyway.

- tools/index_backfill.py: new tool. Walks episodes/<host>/*.tar.zst,
  computes sha256+size, and appends rows for episodes missing from
  the index. Preserves "backfilled: true" so trainers can distinguish
  reconstructed rows. Always opens the index in append mode (never
  replaces), so it cannot reproduce the ownership bug it's recovering
  from.

Regression test: tests/test_prune.py::test_archive_preserves_index_mode.

Operator note for the live receiver: ran the chown fix manually
(chown cis490:cis490 /var/lib/cis490/index.jsonl) and ran the
backfill once to recover 140 elliott-thinkpad rows that 500'd before
the chown landed.
2026-04-30 16:36:05 -05:00
..
__init__.py Add receiver: PUT /v1/episodes ingest with sha256 verify and idempotency 2026-04-28 23:34:04 -06:00
test_episode.py workload audit trail: meta.sample + per-phase events + pre-kill probe 2026-04-30 02:12:34 -05:00
test_exploits.py fleet: rotate exploit modules per (host, slot, ep); Tier 3 by default 2026-04-30 02:22:49 -05:00
test_fleet.py Solvable Tier-3 holes: callback payloads, busybox workloads, bridge by default 2026-04-30 02:32:52 -05:00
test_guest_agent.py Collectors 2/4/5 + fleet runner + sample manifest + Tier-3 setup scripts 2026-04-30 00:02:27 -05:00
test_pcap.py Collectors 2/4/5 + fleet runner + sample manifest + Tier-3 setup scripts 2026-04-30 00:02:27 -05:00
test_perf_qemu.py Close out the open issues: bridge pcap wiring, perf collector, Tier-4 2026-04-30 00:17:49 -05:00
test_proc_qemu.py Add v0 orchestrator + first oracle collector (host /proc) 2026-04-28 23:40:25 -06:00
test_prune.py prune+receiver: preserve index ownership and add a backfill helper (closes #13) 2026-04-30 16:36:05 -05:00
test_qmp.py Close out the deployment-readiness gaps 2026-04-30 00:31:55 -05:00
test_receiver.py Add receiver: PUT /v1/episodes ingest with sha256 verify and idempotency 2026-04-28 23:34:04 -06:00
test_shipper.py shipper: defer SSL context build until cert/CA paths exist (closes #11) 2026-04-30 16:13:59 -05:00
test_tier4.py Close out the deployment-readiness gaps 2026-04-30 00:31:55 -05:00
test_ulid.py Add v0 orchestrator + first oracle collector (host /proc) 2026-04-28 23:40:25 -06:00
test_vm_load_controller.py workload audit trail: meta.sample + per-phase events + pre-kill probe 2026-04-30 02:12:34 -05:00