"""Unit: provenance assembly + serialization.""" from __future__ import annotations import unittest from bot_bottle.orchestrator.model import RunRecord from bot_bottle.orchestrator.provenance import build_provenance, ops_from_log, provenance_to_dict def _record() -> RunRecord: return RunRecord( owner="didericis", repo="bot-bottle", issue_number=17, slug="impl-17", agent_name="impl", bottle_names=["claude"], last_checkin_at="2026-07-01T00:05:00-04:00", ) class ProvenanceTest(unittest.TestCase): def test_ops_from_log(self): ops = ops_from_log([ {"at": "T1", "op": "read_pr", "target": 5, "detail": "ok"}, {"at": "T2", "op": "signal_done", "target": None, "detail": "success: done"}, ]) self.assertEqual(2, len(ops)) self.assertEqual("read_pr", ops[0].op) self.assertIsNone(ops[1].target) def test_build_and_serialize(self): ops = ops_from_log([{"at": "T1", "op": "post_comment", "target": 17, "detail": "ok"}]) prov = build_provenance( _record(), ops=ops, started_at="2026-07-01T00:00:00-04:00", finished_at="2026-07-01T00:05:00-04:00", exit_code=0, watchdog_fired=False, ) d = provenance_to_dict(prov) self.assertEqual("impl-17", d["slug"]) self.assertEqual("didericis", d["owner"]) self.assertEqual(["claude"], d["bottles"]) self.assertEqual(0, d["exit_code"]) self.assertFalse(d["watchdog_fired"]) self.assertEqual(1, len(d["ops"])) self.assertEqual("post_comment", d["ops"][0]["op"]) def test_watchdog_flag_serialized(self): prov = build_provenance( _record(), ops=(), started_at="", finished_at="", exit_code=None, watchdog_fired=True, ) self.assertTrue(provenance_to_dict(prov)["watchdog_fired"]) if __name__ == "__main__": unittest.main()