feat: advance repository records and provenance

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
tegwick 2026-08-21 22:07:48 +02:00
parent 329af60753
commit 35e86d7b85
24 changed files with 1618 additions and 51 deletions

View file

@ -0,0 +1,78 @@
"""Parse repository-owned intake and decision records from Markdown YAML fences."""
from __future__ import annotations
import re
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
import yaml
_YAML_FENCE_RE = re.compile(r"```ya?ml\s*\n(.*?)\n```", re.DOTALL | re.IGNORECASE)
SUPPORTED_RECORD_KINDS = frozenset({"intake", "decision"})
@dataclass
class ParsedRecord:
kind: str
id: str
title: str | None
status: str | None
uuid: str | None
source_path: str
raw: dict[str, Any] = field(default_factory=dict)
block_start: int = 0
block_end: int = 0
def parse_record_text(text: str, *, relative_path: str) -> list[ParsedRecord]:
"""Return intake/decision records embedded in YAML fenced blocks."""
records: list[ParsedRecord] = []
for match in _YAML_FENCE_RE.finditer(text):
try:
data = yaml.safe_load(match.group(1)) or {}
except yaml.YAMLError:
continue
if not isinstance(data, dict) or data.get("kind") not in SUPPORTED_RECORD_KINDS:
continue
record_id = data.get("id")
if record_id is None:
continue
kind = str(data["kind"])
uuid_field = "state_hub_intake_id" if kind == "intake" else "state_hub_decision_id"
records.append(
ParsedRecord(
kind=kind,
id=str(record_id),
title=str(data["title"]) if data.get("title") is not None else None,
status=str(data["status"]) if data.get("status") is not None else None,
uuid=str(data[uuid_field]) if data.get(uuid_field) is not None else None,
source_path=relative_path,
raw=data,
block_start=match.start(),
block_end=match.end(),
)
)
return records
def parse_record_file(path: Path, *, repo_root: Path) -> list[ParsedRecord]:
return parse_record_text(
path.read_text(encoding="utf-8"),
relative_path=str(path.relative_to(repo_root)),
)
def iter_record_files(repo_root: Path) -> list[Path]:
"""Find only the governed record locations; do not interpret arbitrary docs."""
files: set[Path] = set()
for relative in ("intakes", "decisions", "docs/intakes", "docs/decisions", "workplans"):
root = repo_root / relative
if root.is_dir():
files.update(path for path in root.rglob("*.md") if not path.name.startswith("."))
for name in ("INTAKES.md", "DECISIONS.md"):
path = repo_root / name
if path.is_file():
files.add(path)
return sorted(files)