Skip to content

Require a Standing block in new decisions files, and backfill the five split out on 2026-10-19 - #776

Merged
derek73 merged 7 commits into
masterfrom
feat/standing-in-new-decisions
Oct 20, 2026
Merged

derek73 merged 7 commits into
masterfrom
feat/standing-in-new-decisions

Conversation

@derek73

@derek73 derek73 commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Part of #762. C1's ## Standing block landed on 2026-10-19 (#743), and the five decisions files split out the same day (C13, C14, P8, P9, T5) had none. #762 asks whether to roll Standing out to the old logs. New files don't carry that cost: a file's first entry is the cheap moment to write its block. So this PR makes new files carry one and leaves the old ones to #762.

What changes

  • decisions/README.md and root AGENTS.md: a new decisions file opens with ## Standing and ## Log. The rule dates from C1's block landing; C12 and vocabulary-model were created earlier that day and are exempt.
  • A ratchet, not prose. tests/v2/decisions_without_standing.json lists the 88 older files allowed to lack a block. test_a_decisions_file_off_the_list_opens_with_standing fails on:
    • a file off the list with no block. The heading must sit on a line of its own; the words quoted in prose don't count;
    • a listed file that has gained a block (it should leave the list);
    • a listed key with no file;
    • a listed key outside STANDING_EXEMPT_ORIGINAL, the 88 keys the list held when the rule landed (its size is asserted). So a new file can't join the list, alone or swapped in for one that leaves;
    • a heading that misspells ## Standing: a trailing space, another level, or indented. Otherwise a misspelled heading would switch every check off for that file.
  • Placement: standing_findings reports a ## Log before the Standing block as a finding. A block after the log used to crash it.
  • Standing blocks for C13, C14, P8, P9 and T5, each line pointing at the entry that decided it. Writing them, and then reviewing them, turned up stale or overstated facts:
  • A decision of another rule's that a log is the record of stays a bullet naming its rule: C13's line for C2 and P9's for S5. One recorded under another key is an Elsewhere: line.

Review

Run in this order:

  • Two design-docs-reviewer rounds before the PR opened.
  • A three-reviewer PR review: code, test coverage and comments.
  • Two further rounds on its fix commits.

Every finding is fixed. The last round's one leftover, an indented heading, is fixed in a3c2265, which no reviewer has re-checked. Each new test row was run against the commit before it and fails there.

Outside this PR: P9's dated log claims DOE, JANE PHD VD PROF. MA reads middle 'VD PROF.', but it now reads family 'VD DOE', suffix 'PHD, MA'. That's a measurement in a dated entry, not a Standing line, so it's left for whoever revisits P9.

Test plan

  • uv run pytest, after merging master: 22,063 passed, 123 skipped, 3 xfailed
  • uv run mypy, uv run ruff check
  • Negative controls: the real-tree test fails on origin/master's five files, and every synthetic row fails on the commit before the check it pins

🤖 Generated with Claude Code

derek73 and others added 3 commits October 19, 2026 23:54
…e split out today

C1's Standing block landed on 2026-10-19, and five decisions files
split out the same day (C13, C14, P8, P9, T5) had none. The cheap
moment to write one is a file's first entry, so new files now open with
`## Standing` and `## Log`. tests/v2/decisions_without_standing.json
lists the 88 older files allowed to lack a block, and
test_a_decisions_file_off_the_list_opens_with_standing fails on a file
off the list with no block and on a listed file that has gained one, so
the list only shrinks. Whether the older files get one stays #762.

The five files get blocks indexing what their logs decide. Writing P9's
found its #578 note stale: the silent reading #573 left aside was
reversed by #602, and `Doe, Jane PhD vd Ma` reads suffix 'PhD vd Ma'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
P8's Standing named `e` as the subset's default; #397 added `i` with
the conjunction (decisions/P3), as P8's own log foresaw. C13 and P9
named S2 for the run S8 now states. The list could grow by one JSON
line with nothing noticing: its length is now recorded as
STANDING_EXEMPT_CEILING, so a file joins it only by raising the
ceiling too, and a new row pins that. The README dates the rule from
C1's block landing rather than the calendar day, naming the two
same-day files created before it, and the module no longer calls the
block optional.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second review found the length check missed a swap: a file leaving
the list and a new one joining in the same PR kept the length and
passed. The list now has to stay inside STANDING_EXEMPT_ORIGINAL, the
88 keys it held when the rule landed, so a new file can join it neither
alone nor in exchange; a new-file-swapped-in row pins that. The
ceiling is gone, and the comment beside the constant dates the rule
from C1's block landing as the README does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added docs Documentation fixes and updates tests design labels Oct 20, 2026
@derek73 derek73 self-assigned this Oct 20, 2026
@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.05%. Comparing base (8275e8e) to head (9a76943).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #776   +/-   ##
=======================================
  Coverage   99.05%   99.05%           
=======================================
  Files          47       47           
  Lines        4642     4642           
=======================================
  Hits         4598     4598           
  Misses         44       44           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

derek73 and others added 4 commits October 20, 2026 00:19
Three reviewers on #776. The ratchet and the pointer checker looked for
the text `## Standing` anywhere, so a new file whose log only quoted the
convention passed as if it carried a block; both now match the heading
on a line of its own (`has_standing`), and a prose-mention row pins it.
A block placed after `## Log` crashed the pointer checker on unpacking;
it is now a finding. The exempt set's size is asserted, and the row
assertions name the message that should fire.

C14's Standing omitted its own exception (a run a credential opens
takes the vetoed word, `Smith, PSM I.`). P8's said a single-letter
connective joins at every length; it joins only where P3's count lets
it, and the every-length claim is the `initial` tag's. P9's line for
S5's site becomes an `Elsewhere:` pointer; C13's line for C2 stays a
bullet, since no decisions file is keyed C2. The README names all four
ratchet failures and the Elsewhere form, and root AGENTS.md's
new-decisions-key sentence names the Standing requirement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
P9's `Elsewhere:` pointer for S5's site was a loop: decisions/S5's
#573 entry names P9's as the record, so the line is a bullet again,
and the README's Elsewhere example now cites the rule rather than a
case that does not fit it. A `## Log` anywhere before the Standing
heading is a finding (a Log, Standing, Log file used to pass). Matching
the exact heading had quietly narrowed what the substring test caught,
so a heading that misspells it (a trailing space, another level) is
now a finding instead of switching every check off for the file. P8's
example showed nothing the tag decides: `john e smith` gives the same
initials either way, and the line now cites the capitalization and the
report that do differ. Each new row fails on the previous commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Markdown renders a heading indented up to three spaces, and neither
the exact match nor the misspelling check saw one, so a block under it
would have switched the checks off for an exempt file. The misspelling
check now allows leading whitespace, pinned by a row that fails on the
previous commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73
derek73 merged commit a0edfed into master Oct 20, 2026
12 checks passed
@derek73
derek73 deleted the feat/standing-in-new-decisions branch October 20, 2026 07:34
derek73 added a commit that referenced this pull request Oct 21, 2026
Three reviewers on #795. Pointer resolution:
- words that continue no candidate's head are now a finding where
  candidates share a date and issue, so a typo (`#718 reveiw`) no
  longer falls back to the bare entry in silence;
- the longest head the words continue wins, so an entry whose head
  another's extends (`review`, `review round`) can be named;
- a head's words are matched against the whole rest of the line, so a
  period inside them (`v2.4`) no longer cuts them, and a date inside
  them is part of the pick rather than a second pointer;
- an issue is the pointer's only when no comma or parenthesis stands
  between it and the date, so prose after a date-only pointer
  (`— 2026-09-24, see #500`) is not read as its issue;
- `_clean` drops a supersession note in any case, and a parenthesis
  never closed is text.
The 68 real pointers resolve exactly as before (compared against the
previous resolver). New rows fail on the previous commit for the new
behavior; the reviewers' mutation rows (twins differing by a note,
"opens with", a trailing space, the bare-sibling pins) pass there and
kill the mutants they were written for.

Blocks: H3's #316 entry marks the `Dr Smith V` reading S10's #718
reversed, missed when the block was written; H3's numeral example shows
its title; S10's report line also points at #718's PR review; S4 says
"left as it is" as its entry does. README: the pointer sentence states
the new behavior, #776's two cases are attributed to writing and
review, and the batch's count is dated and includes H3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73 added a commit that referenced this pull request Oct 21, 2026
…795)

* Index S3, S4, S6, S10, H3 and P5 with Standing blocks (#762, gate files)

The gates phase 2 of the vocabulary model (#752) will re-read: each
file now opens with what is in force and the entry that decided it,
and leaves the exempt list (88 -> 82).

Writing them found four entries whose heads did not say a later
decision had replaced part of them, now marked under the README's edit
kind 1: S6's accepted `abdul Smith Jr Ma` (reversed by S7's #544), S4's
`Doe, Jane nee Smith MA` maiden reading (by M2's #601), P5's view
comparison (by #614), and S10's one-case `v` (by #721). The README's
Standing bullet now says to look for those first, across the folder,
naming the cases #776 and this batch found.

S6 holds two entries dated 2026-09-14 and two dated 2026-09-18 with no
issue, which a date-only pointer could not tell apart; a pointer may
now carry the words that open its entry's head (`— 2026-09-14 (Derek)`),
and a bare-date head never matches a qualified pointer. New rows pin
both; the qualified ones fail on the previous checker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix the review's findings: every pointer resolves to one entry

The checker let an issue pointer name several entries of one date and
issue, and two S10 lines landed on the wrong sibling (#718's report
entry for its comma review, #721's for its PR review) with nothing
failing. A pointer now resolves to exactly one entry: where several
share its date and issue it goes on with the words the entry's head
continues with (`— 2026-10-18 #718 review`), a bare pointer names the
entry whose head ends there, and one still naming entries with
different heads is a finding. A parenthesized supersession note in a
head is not read, so marking an entry does not break its pointers.
P8's #383 lines were ambiguous among three entries and now name
`#383 + #479` or `#383/#479`. A test pins each target, since a pointer
landing on a sibling passes every finding.

S4's maiden line cited a family-comma example #601 had taken out of
the clause; it cites the comma-less one, and the head marker names
both things #601 superseded there. P5's three family-comma and
name-word clauses come from #425 (PR #426), whose paragraphs #614's
bullet was inserted into on 2026-10-07; the line points there, the
marker names the #369 application #614 also superseded, and an edit
kind 2 note says where the paragraphs belong. S10 marks its two
in-file reversals, S6 its marker issue-first and its helper's callers
without a short list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Tell twin entries apart by how their text opens

The second review found two P8 entries with the same head words
(`2026-09-13 #383/#479`), so each Standing line pointing there landed on
both and the checker passed it, a row having blessed that. Where heads
are the same words, the pointer now goes on with the words its entry's
text opens with (`— 2026-09-13 #383/#479, AMENDS`), and a pointer still
naming more than one entry is ambiguous, twins included. The target
test pins both twins; the unqualified row fails on the previous checker.

Also: S10's #721 PR-review entry marks the mechanism #722 replaced, and
S6's helper sentence no longer says only later stages call it (segment
runs before classify).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pass re.split's maxsplit by keyword

Python 3.13 deprecated the positional form, and CI runs with
DeprecationWarning as an error, so the three newest build jobs failed
on the pointer resolver while 3.11 and 3.12 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Record the newer-interpreter deprecation trap in AGENTS.md's Gotchas

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix the PR review's findings on pointer resolution and the blocks

Three reviewers on #795. Pointer resolution:
- words that continue no candidate's head are now a finding where
  candidates share a date and issue, so a typo (`#718 reveiw`) no
  longer falls back to the bare entry in silence;
- the longest head the words continue wins, so an entry whose head
  another's extends (`review`, `review round`) can be named;
- a head's words are matched against the whole rest of the line, so a
  period inside them (`v2.4`) no longer cuts them, and a date inside
  them is part of the pick rather than a second pointer;
- an issue is the pointer's only when no comma or parenthesis stands
  between it and the date, so prose after a date-only pointer
  (`— 2026-09-24, see #500`) is not read as its issue;
- `_clean` drops a supersession note in any case, and a parenthesis
  never closed is text.
The 68 real pointers resolve exactly as before (compared against the
previous resolver). New rows fail on the previous commit for the new
behavior; the reviewers' mutation rows (twins differing by a note,
"opens with", a trailing space, the bare-sibling pins) pass there and
kill the mutants they were written for.

Blocks: H3's #316 entry marks the `Dr Smith V` reading S10's #718
reversed, missed when the block was written; H3's numeral example shows
its title; S10's report line also points at #718's PR review; S4 says
"left as it is" as its entry does. README: the pointer sentence states
the new behavior, #776's two cases are attributed to writing and
review, and the batch's count is dated and includes H3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Restore the pointer's issue window; end words at the next pointer

The re-review found the fix commit narrowing what it widened: limiting
the date-to-issue window to 20 characters with no comma or parenthesis
stopped a pointer copied whole from its head (`2026-09-19 (Derek),
#533`) from reading its issue, and where a bare sibling shared the date
it resolved to that sibling in silence. The 40-character window is
back; an issue written in prose right after a date-only pointer is
again read as the pointer's and fails loudly, which the module comment
now says. Every head in the files with Standing blocks, copied whole,
resolves to its own entry but P8's twins, which fail as ambiguous.

The words after a pointer now end at the next pointer's date as well
as at `.` or `;`, so `— 2026-10-17 #718, 2026-10-18 #721` reads both;
a Not-standing line's unmatched words are reported as such rather than
as "no entry"; the docstring lists the unmatched-words finding, and
the README says prose after a shared-date pointer goes after a `.` or
`;`. The real pointers number 70, not the 68 the previous message
gave; all resolve as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Read a date inside an entry's head words in every case

The re-review found two shapes where a date inside the words a pointer
continues its entry's head with was still read as a second pointer:
with one candidate, where resolution returned before reading any words
(S4's head copied whole, `2026-09-14 (Derek), scope corrected
2026-09-18`, also cited S4's separate 2026-09-18 entry), and with the
words cut short at that date, new in the previous commit. The words a
resolved pointer read are now its common prefix with the named entry's
head continuation, in every branch. Two rows, whose inner dates name no
entry so that a stray second pointer fails, fail on the previous
commit. The 64 real lines resolve as before, and every head copied
whole now resolves to its own entry except the two pairs of twins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Stop a pointer's issue window at another date

A date-only pointer joined by a comma to a pointer with an issue
(`— 2026-09-24, 2026-10-23 #741`) read that issue as its own, the
window between a date and its issue letting a second date through. The
window now stops at another date, as it stops at `—`, `.` and `;`.
The new row fails on the previous commit; the real lines resolve as
before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count the read prefix by hand; os.path.commonprefix is deprecated in 3.15

The 3.15 build jobs failed on 2a26d17: os.path.commonprefix warns
there, and warnings are errors. The trap is the one AGENTS.md's Gotcha
added in this PR records, and 2a26d17 was not run on 3.15 before it
was pushed. The full suite now passes on 3.15 and 3.11.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

design docs Documentation fixes and updates tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant