session-memory: distributor base + Artifact (WP-0007 T01)

distribute/base.py: Artifact dataclass + Distributor protocol + idempotent
BEGIN/END snippet markers (upsert_block replaces a pattern's block in place so
re-distribution doesn't duplicate) + agnostic markdown body rendering from
SolutionPattern fields. BaseDistributor honours per-flavor body/target hints.
8 new tests; suite 110/110.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 15:02:47 +02:00
parent 9e6f8a6e08
commit 7646cbc358
4 changed files with 213 additions and 1 deletions

View File

@@ -0,0 +1,88 @@
"""Distributor base tests (WP-0007 T01): markers, idempotent upsert, rendering."""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from session_memory.curate.schema import Resolution, SolutionPattern # noqa: E402
from session_memory.distribute.base import ( # noqa: E402
Artifact,
BaseDistributor,
Distributor,
render_markdown_body,
upsert_block,
wrap_block,
)
def _pattern(pid="sp-x", polarity="problem"):
return SolutionPattern(
id=pid, name="Read before edit", version="1.2.0", polarity=polarity,
problem="Agents edit files they have not read.",
resolutions=[Resolution(summary="Read the file first", detail="then Edit",
steps=["Read", "Edit"])],
rendering_hints={"claude": {"target": "CLAUDE.md"}},
)
def test_render_markdown_body_has_problem_and_resolution():
body = render_markdown_body(_pattern())
assert "### Read before edit" in body
assert "Agents edit files" in body
assert "**Avoid:**" in body # problem polarity
assert "- Read the file first — then Edit" in body
assert " - Read" in body
def test_success_polarity_label():
assert "**Prefer:**" in render_markdown_body(_pattern(polarity="success"))
def test_wrap_block_has_markers_and_version():
block = wrap_block("sp-x", "hello", "1.2.0")
assert block.startswith("<!-- BEGIN helix-forge pattern:sp-x --> v1.2.0")
assert block.rstrip().endswith("<!-- END helix-forge pattern:sp-x -->")
def test_upsert_inserts_then_replaces_in_place():
doc = "# Title\n\nsome text\n"
b1 = wrap_block("sp-x", "first", "1")
once = upsert_block(doc, "sp-x", b1)
assert "first" in once and once.count("BEGIN helix-forge pattern:sp-x") == 1
# re-distributing the same id replaces, does not duplicate
b2 = wrap_block("sp-x", "second", "2")
twice = upsert_block(once, "sp-x", b2)
assert "second" in twice and "first" not in twice
assert twice.count("BEGIN helix-forge pattern:sp-x") == 1
def test_upsert_keeps_other_patterns():
doc = upsert_block("", "sp-a", wrap_block("sp-a", "A"))
doc = upsert_block(doc, "sp-b", wrap_block("sp-b", "B"))
assert "sp-a" in doc and "sp-b" in doc
def test_base_distributor_renders_artifact():
d = BaseDistributor(flavor="claude", target_path="CLAUDE.md")
art = d.render(_pattern())
assert isinstance(art, Artifact)
assert isinstance(d, Distributor) # satisfies the protocol
assert art.flavor == "claude"
assert art.target_path == "CLAUDE.md"
assert "BEGIN helix-forge pattern:sp-x" in art.content
assert "Read before edit" in art.content
def test_body_hint_overrides_default():
p = _pattern()
p.rendering_hints["claude"]["body"] = "custom claude body"
d = BaseDistributor(flavor="claude", target_path="CLAUDE.md")
assert "custom claude body" in d.render(p).content
def test_target_hint_overrides_default():
p = _pattern()
p.rendering_hints["claude"]["target"] = "docs/CLAUDE.md"
d = BaseDistributor(flavor="claude", target_path="CLAUDE.md")
assert d.render(p).target_path == "docs/CLAUDE.md"