A local-first utility that extracts narrowly defined status claims from authoritative development artifacts and reports deterministic contradictions with exact source spans. It helps prevent stale README text, plan markers, issue exports, and next-action pointers from sending operators or agents in incompatible directions.
| Tool | Why |
|---|---|
| Python 3.12+ | Implementation language |
| uv | Environment + dependency management |
| argparse | CLI |
| pytest | Golden parser, contradiction-rule, and suppression tests |
| Ruff | Lint + format |
| mypy (strict) | Static typing |
- Python 3.12+
- uv
uv sync --extra dev
uv run pytest -q
uv run ruff check .
uv run mypy --strict srcsame-page check [manifest]The optional positional manifest defaults to same-page.toml discovered at the enclosing git root
of cwd (walk-up discovery); --root <path> overrides the discovery root. No enclosing repo, no
--root, and no explicit manifest path is a usage error — never a heuristic fallback.
Issue exports are produced by
gh issue list --state all --json number,title,state,url,body > issues.json (or any substitute
producer emitting the same JSON shape); --state all because completion-state cross-checks must see
closed issues.
| Code | Meaning |
|---|---|
| 0 | clean — no findings, no parse diagnostics |
| 1 | contradiction findings present |
| 2 | parse diagnostics present |
| 64 | usage error (EX_USAGE) |
Precedence: highest applicable code wins (2 > 1 > 0), so incomplete parses are never masked.
# same-page.toml
schema_version = 1
approved_roots = ["."]
[[artifact]]
path = "plans/plan.md"
role = "canonical-plan" # canonical-plan | readme-summary | issue-export# suppressions
schema_version = 1
[[suppression]]
rule_id = "SP-STATE-001@v1"
artifact = "README.md"
claim_key = "step-4"
rationale = "README intentionally summarizes at phase level"
expires = "2026-09-01"- Artifact roles are explicit. A manifest identifies the canonical plan and secondary summaries;
authority is never guessed from whichever file changed most recently. Approved roots are exactly
the manifest's
approved_rootsentries; any path resolving outside them fails explicitly. - Deterministic v1. Rules compare normalized fields (phase, completion state, next step, issue state, referenced id). Open-ended semantic detection is deferred; confidence is omitted from all v1 contracts (deliberate, documented deviation from the seed guardrail).
- Parse failure is not consistency. Malformed artifacts produce diagnostics and a non-clean result rather than disappearing.
- Suppression is evidence-bearing. Suppressions carry rule, sources, rationale, and expiry; match key = rule_id + canonicalized artifact path + normalized claim key (no line/column).
- Rule identifiers.
SP-<AREA>-<NNN>@v<M>(e.g.SP-STATE-001@v1), defined once inrules.py; a version bump supersedes.
src/same_page/
models.py claim, source span, finding, parse-diagnostic shapes
manifest.py explicit artifact roles + precedence
readers/ plan, README, issue-export parsers
rules.py deterministic contradiction predicates
suppressions.py scoped, expiring suppressions
cli.py same-page check
See plans/plan.md for the frozen field contracts.