refactor(pi): generate modular session instructions (#25)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""Deterministic builder for the single Pi-facing Thoth session skill."""
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
|
||||
HARNESS_ROOT = Path(__file__).resolve().parents[1]
|
||||
SKILL_ROOT = HARNESS_ROOT / ".pi" / "skills" / "tht-sessione"
|
||||
MODULE_ROOT = SKILL_ROOT / "modules"
|
||||
TEMPLATE_PATH = SKILL_ROOT / "projection.md.tmpl"
|
||||
PROJECTION_PATH = SKILL_ROOT / "SKILL.md"
|
||||
|
||||
# This tuple is the composition contract. Never derive it from directory order.
|
||||
FRAGMENT_ORDER = (
|
||||
("{{DISAMBIGUATION_OPEN_AMBIGUITY}}", "disambiguation/open-ambiguity.md"),
|
||||
("{{DISAMBIGUATION_INSTRUCTIONS}}", "disambiguation/phase-1.md"),
|
||||
("{{MEMORY_INSTRUCTIONS}}", "memory/phase-2.md"),
|
||||
("{{DISAMBIGUATION_REWRITING_INSTRUCTIONS}}", "disambiguation/phase-3.md"),
|
||||
("{{MEMORY_SOLVED_SEARCH_F4}}", "memory/solved-search-f4.md"),
|
||||
("{{DISAMBIGUATION_SCHEMA_GROUNDING}}", "disambiguation/schema-grounding.md"),
|
||||
("{{MEMORY_SOLVED_SEARCH_F6}}", "memory/solved-search-f6.md"),
|
||||
("{{MEMORY_SOLVED_SEARCH_F7}}", "memory/solved-search-f7.md"),
|
||||
("{{MEMORY_PROMOTION_F8}}", "memory/phase-8-promotion.md"),
|
||||
("{{MEMORY_SOLVED_FINALIZATION}}", "memory/solved-finalization.md"),
|
||||
)
|
||||
|
||||
|
||||
def render_projection(*, template: bytes | None = None) -> bytes:
|
||||
projection = TEMPLATE_PATH.read_bytes() if template is None else template
|
||||
for marker_text, filename in FRAGMENT_ORDER:
|
||||
marker = marker_text.encode()
|
||||
if projection.count(marker) != 1:
|
||||
raise ValueError(f"projection placeholder {marker_text} must occur exactly once")
|
||||
fragment = (MODULE_ROOT / filename).read_bytes().rstrip(b"\n")
|
||||
projection = projection.replace(marker, fragment)
|
||||
return projection
|
||||
|
||||
|
||||
def projection_is_current(path: Path = PROJECTION_PATH) -> bool:
|
||||
return path.exists() and path.read_bytes() == render_projection()
|
||||
|
||||
|
||||
def write_projection(path: Path = PROJECTION_PATH) -> None:
|
||||
path.write_bytes(render_projection())
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
action = parser.add_mutually_exclusive_group(required=True)
|
||||
action.add_argument("--check", action="store_true", help="fail if SKILL.md is stale")
|
||||
action.add_argument("--write", action="store_true", help="regenerate SKILL.md")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.write:
|
||||
write_projection()
|
||||
print(f"generated {PROJECTION_PATH}")
|
||||
return 0
|
||||
if projection_is_current():
|
||||
print(f"up to date: {PROJECTION_PATH}")
|
||||
return 0
|
||||
print(
|
||||
f"stale projection: run `python -m tht.pi_skill_projection --write` from {HARNESS_ROOT}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user