generated from coulomb/repo-seed
feat(coordination): git backend wiring + verbatim log migration (WP-0009 T4)
InformationSpace.git_backed(space_id, repo_path) wires the git coordination log; the default constructor stays in-memory for tests (new keyword-only store=). A one-time importer (migrate_space / import_log / JSONL export+import) replays an existing in-memory or JSON log into git verbatim — preserving seq, timestamp and actor (union-without-erasure) and refusing out-of-order import. Same fold after migration; no behavioural change to overlay/union. SCOPE updated; WP-0009 done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
74
tests/test_coordination_migration.py
Normal file
74
tests/test_coordination_migration.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Migration + wiring of the git coordination backend (SHARD-WP-0009 T4)."""
|
||||
|
||||
from shard_wiki.coordination import (
|
||||
DecisionLog,
|
||||
EventType,
|
||||
GitEventStore,
|
||||
InMemoryEventStore,
|
||||
export_jsonl,
|
||||
import_jsonl,
|
||||
migrate_space,
|
||||
)
|
||||
from shard_wiki.space import InformationSpace
|
||||
|
||||
|
||||
def test_information_space_git_backed_uses_git_log(tmp_path):
|
||||
space = InformationSpace.git_backed("space-1", tmp_path / "coord")
|
||||
assert isinstance(space.log._store, GitEventStore)
|
||||
space.alias("Home", "shardA:Index")
|
||||
# Read-your-writes through the orchestrator's git-backed log.
|
||||
assert space.log.fold("space-1").resolve_alias("Home") == "shardA:Index"
|
||||
|
||||
|
||||
def test_default_information_space_stays_in_memory():
|
||||
space = InformationSpace("space-1")
|
||||
assert isinstance(space.log._store, InMemoryEventStore)
|
||||
|
||||
|
||||
def test_migrate_space_preserves_order_and_provenance(tmp_path):
|
||||
source = InMemoryEventStore()
|
||||
e0 = source.append("s", EventType.ALIAS_SET, {"alias": "Home", "target": "x:1"}, actor="ana")
|
||||
source.append("s", EventType.BINDING_MADE, {"members": ["a", "b"]}, actor="ben")
|
||||
|
||||
dest = GitEventStore(tmp_path / "coord")
|
||||
n = migrate_space(source, "s", dest)
|
||||
assert n == 2
|
||||
|
||||
migrated = dest.events("s")
|
||||
assert [e.seq for e in migrated] == [0, 1]
|
||||
# Provenance preserved verbatim — actor and timestamp survive the move (no restamping).
|
||||
assert migrated[0].actor == "ana"
|
||||
assert migrated[1].actor == "ben"
|
||||
assert migrated[0].timestamp == e0.timestamp
|
||||
|
||||
|
||||
def test_migration_yields_identical_fold(tmp_path):
|
||||
source = DecisionLog(InMemoryEventStore())
|
||||
for typ, payload in [
|
||||
(EventType.ALIAS_SET, {"alias": "Home", "target": "x:1"}),
|
||||
(EventType.BINDING_MADE, {"members": ["a", "b"]}),
|
||||
(EventType.BINDING_MADE, {"members": ["b", "c"]}),
|
||||
(EventType.ALIAS_SET, {"alias": "Home", "target": "x:2"}),
|
||||
]:
|
||||
source.append("s", typ, payload)
|
||||
|
||||
dest = GitEventStore(tmp_path / "coord")
|
||||
migrate_space(source._store, "s", dest)
|
||||
after = DecisionLog(dest)
|
||||
assert after.fold("s").aliases == source.fold("s").aliases
|
||||
assert after.fold("s").equivalence_groups == source.fold("s").equivalence_groups
|
||||
|
||||
|
||||
def test_jsonl_round_trip_into_git(tmp_path):
|
||||
source = InMemoryEventStore()
|
||||
source.append("s", EventType.ALIAS_SET, {"alias": "Home", "target": "x:1"})
|
||||
source.append("s", EventType.PAGE_FORKED, {"source": "p", "fork": "q"})
|
||||
|
||||
path = tmp_path / "log.jsonl"
|
||||
assert export_jsonl(source.events("s"), path) == 2
|
||||
|
||||
dest = GitEventStore(tmp_path / "coord")
|
||||
assert import_jsonl(path, dest) == 2
|
||||
state = DecisionLog(dest).fold("s")
|
||||
assert state.resolve_alias("Home") == "x:1"
|
||||
assert state.equivalent_to("p") == frozenset({"p", "q"})
|
||||
Reference in New Issue
Block a user