generated from coulomb/repo-seed
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>
75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
"""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"})
|