Repository navigation
check-stacked-prs.py is named in no tracked document, and the agent brief has no room for it #1888
Description
scripts/check-stacked-prs.py landed on 2026-10-06 (PR #1885, issue #1884) and, measured the next day, is named in no tracked document: not in Agent.md's merge-gate list, not in DEVELOPMENT.md, not in evolution_prompt.md. Its only carriers are its own docstring, tests/test_check_stacked_prs.py, and the private .emrg/ records — and it exists because a reading was missing: its own docstring records that "no reading in this repository caught it" and that a reviewer found the stacked head (#1879 carrying #1877's commits) by reading the API by hand.
So the fix for a missing reading is a reading the next reviewer has no way to learn about. The failure mode is exactly the one this repository mechanises against everywhere else: a gate that is not run is not a gate.
Why it is not simply a line in the brief
Agent.md is the one document both the agent and the cycle are guaranteed to receive — and it is at its prompt cap: measured here, 7997 of the PROJECT_CONTEXT_MAX_CHARS (8000) characters the daemon keeps (tests/test_agent_md_prompt_cap.py). Adding the gate as that list spells its members ( · \scripts/check-stacked-prs.py` (a head carrying another open PR's commits)`, 77 characters) puts the file at 8074, past the cap, and the daemon would silently drop the brief's tail — which is where its conventions live.
The two other ways out were both measured this cycle and both cost more than they look:
- Stating the directory once instead of
scripts/nine times (72 characters, which pays for the new entry with room to spare) breaks three pins that require the runnable invocation spelled with its path in that line —tests/test_check_vote_count.py::test_agent_md_documents_the_canonical_invocation,tests/test_check_merge_tree_health.py::test_agent_md_documents_the_canonical_invocation,tests/test_the_tree_health_gate_is_described_as_one_guard.py::test_agent_md_says_the_gate_passes_one_guard— because a bare name is not a command (scripts/*.pyis mode 644). That is a doc-format change with cross-cutting cost, not an edit. - Freeing space elsewhere means the derived per-file Node counts in the
GUI:/Renderer:rows (~700 characters), which are the subject oftests/test_doc_counts.pyandscripts/check-node-test-count.py. Removing them is a policy decision, not a cleanup.
What this PR does
DEVELOPMENT.mdgains the gate, in its runnable form, with the question it answers (its temporary home).tests/test_check_stacked_prs.pypins both, and measures the reason rather than restating it: the entry is absent fromAgent.md's list and adding it would exceed the cap. The day the brief has room, that arm fails and says to move the entry into the list and delete the stand-in paragraph — so a temporary home cannot outlive its reason.
What it leaves open (host decision)
Which content pays for the gate in Agent.md: the per-file Node breakdowns are derived data that a tool already syncs, and Agent.md's own header says the file is "principles and conventions only" — but deleting them changes two guards' subject, so it is a call for the host rather than for a cycle.
Acceptance
uv run pytest tests/ -vpasses.DEVELOPMENT.mdcarriesuv run --no-sync python3 scripts/check-stacked-prs.pyand the question it answers.- Removing the runner from that line fails the pin; making the entry fit in
Agent.mdfails the measured-reason arm with the instruction to move it.
Activity
how2how2how2-arch commentedon Oct 7, 2026
Handled by #1889