Repository navigation
docs(process): four corrections found in review, two of them missing criteria (#16126, #15953) - #16127
Merged
Conversation
…criteria (#16126, #15953) A closure audit on #15953 found three of five acceptance criteria met, so it stays open and these are the two that were not, plus two review findings on the merged text. AC4 -- INSTANCES ARRIVE WITH EVIDENCE. The document cited three issues against roughly twenty described instances, which is assertion wearing the clothes of evidence and is the shape the page argues against. Citations added where one was filed: #15987 for both ticked-criterion cases, #16089 for js-yaml, #16124 for --author @me, #16087 for the required-contexts premise. Where no issue exists the absence is now stated rather than hidden, and it says something: an instance with no issue number was found and fixed by whoever caused it, in the same change. That is the rarest outcome on the page and never the one to plan for. AC5 -- THE COUNTERWEIGHT, and the one I most wanted back. The whole page trains a reader to distrust a low count. AC5 is the case where the low count is RIGHT: grep "self.config = config" finds 7 and flake8 --select=F821 finds 5, and neither is blind -- they count assignments and undefined names, and the two they differ on are exactly the two files that bind the name. Without it the document teaches a reflex -- "the lower number is the broken instrument" -- that is wrong often enough to cause work. A mismatch is a prompt to compare DEFINITIONS, and either instrument may be the one telling the truth. FAMILY ORDER. The letters run A B C D F, then E. E was written first and is cited by number on #16100 and #13148, so renaming breaks those; the sequence is now stated where F sits instead of left for a reader to trip over. On this page above all, a label that does not match what it labels is the subject. FAMILY D GAINS ITS MECHANISM, supplied by the reviewer from their own gate. D said a correct output can support two causes; it did not say why nobody checks. A merge gate reported STALE PR OBJECT truthfully for an hour while the reviewer supplied a cause it had never reported -- the output correct, the explanation invented on top of it and unexamined, because a refusal feels like it has already been investigated. Nobody audits a "no". That example also draws the line between D and the ladder's second rung: rung 2 is a GUARD answering an adjacent question, D is a PERSON answering one on the guard's behalf. Both #16126 findings came from the session reviewing the document rather than from its author, which is the document's own closing claim arriving as evidence about the document.
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
#16126) New instance for family F, and it is mine from an hour ago. I told a reviewer I had taken two files wholesale from another branch "precisely so there would be no difference to miss", offering that as a reason the supersession did not need checking. They checked anyway. The files DIFFER: black reflowed five regions between the copy and the commit -- a raw string rejoined, a quote style flipped, a signature collapsed, a docstring spaced. The conclusion held. The _ATX_HEADING regex was byte-identical and all four reproduction cases were present, including the two that must keep returning None. But the claim I used to argue against checking was false. "I copied it wholesale" is a correct answer to WHAT DID YOU DO. It was read as an answer to ARE THE FILES IDENTICAL, and those come apart the moment any automated step sits between intent and artefact -- which, in this repo, is always, because the formatter runs on commit. Worth recording because of what the claim was FOR: it was offered as grounds to skip a comparison. A provenance claim that discourages verification is the most expensive kind to get wrong, and the reviewer's line is the rule -- a duplicate that is NEARLY the same is worse than one that is identical, because the difference is what nobody reads.
…ted (#16126) Review observation from the session verifying #16129, and it is a principle the page did not have. The cheapest way to turn a red green is usually to delete the thing being measured. It works, it is fast, and it destroys the value the check existed to defend -- a green worse than the red. Worked example from that PR. A comment failed the line-number citation guard, and deleting the citation would have passed. It would also have removed the reader's route to WHERE the allowance is coarser than it looks, which was the whole reason the sentence existed. The guard forbids line numbers because they rot silently; it does not ask anyone to stop saying where to look. Keeping the symbol and the file and dropping only the number satisfies the rule and keeps the pointer -- invalidated now only by a rename, which is loud. Generalised to the three shapes this repo actually produces: a weak assertion is fixed by asserting the REASON rather than by deleting the assertion, a flagged exemption by RECORDING it rather than by narrowing the pattern until the tree looks clean, and a stuck ratchet by doing the work rather than by raising the baseline. The operative question is not "what makes this pass" -- deletion always makes it pass. It is "what does this check exist to preserve, and does my fix still preserve it?"
…16126) Two instances from the last hour, one of which is the sharpest exemption lesson this page has. AN ALLOWANCE WAS WRITTEN FOR A PACKAGE THAT HAD NO ADVISORY. redocly was justified by a careful upgrade-path analysis -- 1.34.19 is the newest 1.x, a fix exists at 2.51.2, openapi-typescript carets ^1.34.6 so 2.x is unreachable. Every clause true. And beside the point: the audit output said, one line beneath the range, "Depends on vulnerable versions of js-yaml". Redocly was listed only for depending on vulnerable js-yaml, and one patch bump cleared both highs. Author and reviewer both verified the allowance. Both checked the package the exemption NAMED rather than the reason it was NAMED. The justification was rigorous, which is what made it convincing -- and rigour applied one level away from the question is indistinguishable from rigour applied to it. The operative rule: a finding that arrives THROUGH another finding is fixed at the source, and an exemption written for it is a permanent exemption for a condition that was never going to persist. AND AN EMPTY STDOUT WITH AN UNREAD STDERR IS NOT A MEASUREMENT. gh run view --log writes "the response contains terminal escape sequences" to stderr and nothing to stdout, so a piped read returns empty. Two sessions independently read that as the logs being gone -- one published "the logs are expired", the other tried twice and reported an unresolvable gap. --allow-escape-sequences returns 212KB. A tool refusing to answer looks identical to a tool answering nothing.
mrveiss
added a commit
that referenced
this pull request
Sep 9, 2026
…16104, #16122) (#16129) * fix(ci): clear the three defects every open PR is inheriting (#16089, #16104, #16122) Eight red check-runs across nine PRs reduce to three causes, none of which any of those PRs introduced. Fixing them one per PR means three CI suites and three review passes to unblock a queue that is already blocked; fixing them together means one. 1. DEPENDENCY SECURITY SCAN -- js-yaml ~4.3.1 -> ~4.3.2. The advisory range is 4.0.0-4.3.1, so 4.3.2 is outside it and IS the fix. With the redocly allowance already on base, this is the half that clears the scan. Affects #15980, #16088, #16123. 2. PYTHON-SUITE SHARD 7/12 -- a comment citing a line number. comment_line_number_citations_test forbids it, and security.yml carried `security_scan_gate.py:100` from a merge earlier today. Mine. A line number is invalidated by edits to code it does not describe and fails silently into whatever later occupies it -- and it was written inside a paragraph warning that the allowance is coarser than it looks. Symbol name only now. Affects #15980, #16106, #16107, #16117, #16125. 3. CHECK SAME-SCOPE BATCHING -- an ATX heading needs `#` followed by a space. check_pr_issue_batching.py treated any line starting with `#` as the next heading, so a rationale opening `#15961 alone...` made a FILLED section parse as empty. The message now also distinguishes "no section found" from "section found but empty", quoting the line that ended the parse -- because a red only self-corrects when it names its real cause, and every previous author here reworded until green, leaving no trace. Affects #16117, #16119, #16123, #16127. TAKING DEPENDABOT'S WHOLE package.json WOULD HAVE REGRESSED SIX PACKAGES, and that is the reason this is assembled by hand rather than merged from its branch. #16088 was cut before several upgrades landed, so adopting the file wholesale downgrades apexcharts 7.1.0->6.10.0, cytoscape 3.34.2->3.34.1, onnxruntime-web 1.29.0->1.26.0, vega-embed 7.2.0->7.1.0, vue-i18n 11.4.10->11.4.8 and vue-router 5.3.1->5.2.0. Caught by reading the diff rather than the intent. So the frontend change is exactly one line of package.json and three lines of the lockfile -- version, resolved and integrity for node_modules/js-yaml, copied verbatim from dependabot's verified entry rather than invented. The nine remaining `4.3.1` strings in the lockfile are debug, @types/esrecurse, ansis and polished; dependabot's own lockfile has the same nine. 44 tests pass: the batching parser's full suite including the four reproduction cases, and the citation guard that shard 7 was failing on. * security: drop the redocly allowance -- the scanner stopped reporting it (#16089) The gate failed on the allowance itself: allowance(s) ['@redocly/openapi-core'] name findings the scanner no longer reports. Remove them; an allowance that matches nothing tolerates whatever appears next. Not the advisory returning. The advisory GOING. This is the self-cleaning property that the allowance was justified against, arriving and doing exactly what it was described as doing -- and it is the third time today that a check I verified has then been right about my own work. Worth being precise about why an empty match is a failure rather than a shrug. An allowance keyed on a package name admits ANY future advisory in that package, so one that currently matches nothing is not inert -- it is a standing exemption for whatever appears there next, with nobody watching. Nothing else in this system asks whether an allowance is still needed, so without this check the entry sits until someone happens to reread the block. The npm gate now carries NO allowances, which is the state to defend. Adding one back needs the evidence the last one had: no reachable fix, checked against the REGISTRY rather than the advisory range -- a fix at a major behind a third party's dependency range is still a fix, which is the distinction that nearly made the js-yaml allowance permanent -- and the package does not ship. #16122's subject was pointing the allowance at a removal tracker. There is no allowance to track, so #16123 is now moot as well as superseded.
…bulary (#16126) Recorded as its own entry rather than folded into name-the-selector, on the handing-off session's argument that collapsing them loses the second. They are mirrors: name-the-selector governs EMPTY results, this governs POSITIVE ones. A guard forbidding refusal-suppression in shipped prompts was written from the six strings in the tree. Probed by a session that had not seen the pattern, against fourteen phrasings absent from it: 6/6 live found, 0/14 unseen found. Every branch was anchored on the lemma refuse/refus, and the fourteenth case was the shipped line WITH ONE WORD CHANGED. After rewriting to two factors in proximity, 17/17. Two rules follow. Measure recall against phrasings not yet in the tree, because a detector matching everything it was built from proves only that it can find its own training set. And keep the corpus in a SEPARATE FILE from the pattern -- a detector holding its own exam invites the fix that makes the test pass, and split, editing the detector and editing what it must catch are two files in the diff. The general form: "broader than the strings I found" is not the same as "broad enough". The first is measured against a population the instrument already saw.
) One workspace count was stated four times by three sessions and was wrong three of them -- 6, 11/12, 14, against a measured 13 -- with four different causes. The last was mine: the glob *package.json matched browser-package.json, a filename that merely ENDS with it. Every one of those was produced by someone looking straight at the number, immediately after watching the previous count fail. Care was not the variable. It was maximal every time. THE TELL IS THAT BEING WRONG NEVER CHANGED A CONCLUSION. The total was never the relevant denominator -- three of those workspaces have no lockfile, so npm audit could not run in them whatever it said. Seven auditable and one audited were correct in every version. So the remedy is not to count more carefully, which had already been tried three times. It is to DELETE THE NUMBER. A figure that cannot change the decision does not earn its place beside one that can, and its presence is not neutral: it is the part a reader checks, and getting it right feels like having checked the claim. The operative question before publishing a count: which decision moves if this is wrong? If none does, it is decoration with the texture of evidence. Diagnosis from the reviewing session, which noticed the pattern across all four attempts rather than only correcting the fourth.
…sit (#16126) My error, through two relays, and the direction of the drift is the finding. An issue reported "a scoped absence" in those words: within autobot-backend/judges/, nothing imports ResponseQualityEvaluator. The author anticipated the misreading and named two real importers in the body. I relayed it and the path fell out -- "six judge modules and not one importing it". A second session forwarded that, and it arrived as NOTHING IMPORTS IT. Measured on base: eight importers, including knowledge/pipeline/cognifiers/recursive_summarizer.py, the production compaction path that #16110 and #16111 are about. Zero within judges/, exactly as filed. THE REMEDIES ARE OPPOSITE. Nothing imports it is dead code -- revive or delete. The judge modules reimplement it is duplicated live code -- converge onto the one that works. The relay substituted the weaker argument while making it sound more dramatic, which is why nobody along the chain felt they had lost anything. The drift is directional. The scoped claim is longer, needs a qualifier and invites "which directory?"; the absolute one is shorter, striking and self-contained. Everything that helps a sentence survive retelling also strips its scope, and nobody adds a path back in. So the selector travels with the result or the result does not travel. Name the selector applies with MORE force to a forwarded claim than a published one: every hop can shed the qualifier and none can recover it.
…on (#16126) Third instrument-level instance of one family today, and the sharpest mechanism. A watcher polled /pages/builds/latest waiting for one build and reported "still building" for its whole life. That build had ERRORED. A second push re-pointed latest, and the watcher -- which had never held a SHA -- saw an unbroken run of building: first one build, then a different one. 12:13:36 a8fad32 errored <- never observed 12:22:01 e1cc415 building <- what latest became The failure was not missed through inattention. It was OVERWRITTEN. The watcher read a pointer rather than a thing, and nothing in the response says which build a status belongs to unless you compare .commit yourself. Related to an endpoint returning a superset of what you meant, and worse in one respect: there the extra rows are visible and filterable, here the row you wanted is gone from the answer and replaced by one that looks identical. The direction is also the dangerous one -- a superseded failure reads as STILL WORKING, which prompts waiting rather than investigating. So key a watch to the identity you care about, never to a positional alias. Any endpoint whose name is a superlative -- latest, head, current -- answers what is at this position NOW, and the position is not what you were asking about. Found by the session running the deployment, when its own watcher timed out without ever seeing the error it was armed to catch.
…16126) Three deploys of one page, no live site, and not one failed on content. a8fad32 queued ~17 min for a runner, then marked errored at the exact second the next push arrived -- my push e1cc415 build SUCCEEDED, deploy job CANCELLED two minutes later by a POST asking for a build, sent because the row looked stuck Pages deploys one at a time, so EACH ATTEMPT TO HELP CANCELLED THE WORK ALREADY IN FLIGHT. The API reported every cancellation as "Page build failed.", duration 0, error detail null -- indistinguishable from a real failure, and it sent two sessions hunting a defect in a page that had built cleanly. The status field cannot separate a slow queue from a stuck job: both show a row that has not moved. And the intuitive response to not-moving -- retry, re-request, re-push -- is exactly the action that destroys the in-progress attempt. The instinct is not useless here, it is the mechanism of the failure. So the question is not "has this stopped moving?" but "is anything working on it right now?" -- a question about a RUNNER, which a status field does not answer. gh run list answers it; pages/builds actively misleads. Where an operation is exclusive, a wrong nudge does not waste a call, it destroys the attempt that was about to succeed. Diagnosed by the session that made the second cancellation and said so, including retracting its own earlier speculation about a first-push race once the Actions runs disconfirmed it.
Corrected instance -- and the correction is the case, not the original claim. GitHub reported NOASSERTION for two repositories whose LICENSE files are Apache-2.0. First reading: the classifier is wrong, the files are fine, reached by running head -3, seeing "Apache License / Version 2.0", and generalising to the file. Both files are 736 bytes -- the Apache-2.0 NOTICE BOILERPLATE, not the licence text. The same project's main LICENSE is 11343 bytes and classifies fine. GitHub matches full licence texts, so NOASSERTION was the CORRECT output for a stub. The instrument was right and our files are incomplete: the exact inverse of the conclusion drawn. A truncated read answers a question about the truncation. head -3 establishes what three lines say and nothing about line four onward, and its danger is that on a file whose opening looks canonical it returns something shaped like confirmation -- so the reader stops. Stopping is the failure, not the command. Two properties would have settled it in one call, neither requiring the file to be read: its SIZE against a known-good example of the same kind, and WHAT THE CONSUMING INSTRUMENT MATCHES ON. Recorded for when it happened. This was committed while writing up a finding about instruments answering narrower questions than intended, by the session that had spent the day finding that failure in other people's guards. Knowing the pattern by name does not exempt the next command you type. Filed separately as #16138 to replace both LICENSE files with full text.
Reframing, because my version named the wrong mechanism. I wrote this as a transmission defect -- a scoped claim losing its qualifier between people, each hop shedding it. The tidiest instance has no relay at all: a research document stated its claim bounded, six named axes with file:line evidence, and the index row summarising it said "our loop design is ahead on every axis". SAME SESSION, SAME DOCUMENT, SAME SITTING. Nothing was retold and the bound was still lost. So the mechanism is compression, and a relay is only the case where it happens repeatedly. Any act of shortening selects for the version without the qualifier, because the qualifier is the part that costs words and invites a question. That widens where to look. Not just messages between sessions, but any summary of something more careful -- and an INDEX ROW is the worst case, because it is the surface people scan to decide whether to open the document, so the scoping ends up in the file they then do not read. Remedy unchanged in substance, wider in scope: the summary carries the bound or it is not a summary of that claim. Where the short form cannot hold the qualifier, quote the original sentence rather than compress it -- a longer row is cheaper than an unbounded claim on the surface most likely to be read alone. Observation from the session that fixed the row rather than merging past it.
gh run list --status in_progress returned 0 while 47 runs sat queued. Read as a condition that is a fleet-wide Actions stall. It was not one -- in_progress is short-lived, the query caught an instant between hand-offs, and a count minutes later showed 5. The value was correct about the moment it was taken. The conclusion was about the system. Any instantaneous count of a transient state is a sample, and a ZERO sample is the most likely to be read as a fact -- "none" sounds like a property of the system where "five" obviously invites "right now?". The misreading is most seductive exactly when the number is alarming. Two defences, neither requiring any understanding of the system: sample twice separated in time, and check the COMPLEMENT -- runs completing proves the pool works far better than runs in flight proves it, and completions are durable where in-flight is not. The general form covers most of this page: prefer the durable signal to the momentary one. A completed run, a merged commit, a file on disk are still true when you look again. A queue position, an in_progress count and a build's latest pointer are photographs of something moving. Caught by the session that made it, before publishing -- the only one of three instrument misses today that did not have to be corrected by someone else.
Two sessions wrote an issue number before filing the issue, on the same day. One predicted #16135 for a follow-up and filed as #16139. #16135 exists -- an unrelated open issue about a 404ing landing page -- so a reader following that citation arrives somewhere real, plausible and wrong. The other was me. I wrote (#16135) into a commit message before filing, then filed and HAPPENED TO GET #16135. Same act, opposite outcome, and the difference was which id was next rather than anything either of us did. A broken reference announces itself. A valid reference to the wrong thing does not: it renders normally, carries a plausible title, and gets believed. It is the more expensive of the two by a wide margin and the one that looks fine in review. So: file first, cite second. Never write an identifier that has not been read back from the system that issues it. Same rule as the rest of this page, applied to a number you PRODUCED rather than one you measured -- a predicted id is a claim about the world, and the world assigns ids without consulting you. The lucky case is the instructive one. Getting away with it produced no error, no correction and nothing to learn from, which is why the habit survives until the day the number is taken.
…ed then (#16126) The predicted-identifier rule got a better diagnosis than the rule itself, from the session that broke it one hour after stating it. They wrote "file first, cite second -- never write an issue number I have not read back from the API", then in the NEXT artefact wrote "Filed as #16140" before filing. It filed as #16140. Correct again, and correct is the worst available outcome: a wrong number gets caught, a lucky one leaves a citation that resolves, a closure that reads as rigorous, and a habit with fresh evidence that it works. Their diagnosis is the part worth keeping. The rule was not forgotten -- it failed where it costs something. A citation gets written WHILE COMPOSING THE REASONING THAT NEEDS IT, so obeying means breaking off mid-argument to go and file. A rule whose price is highest exactly when it applies gets skipped exactly when it applies, and agreeing with it beforehand does not change that. So the version that survives contact is not a stronger commitment but a cheaper action: write a placeholder, finish the argument, fill it in after filing. This is the third time today someone committed the error they were in the middle of documenting. The page already says knowing the pattern by name does not exempt the next command you type; this says WHY, and what to do instead.
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #16126, refs #15953 — delivers that issue's two outstanding acceptance criteria.
Thinking Path
A closure audit on #15953 after #16102 merged found three of five criteria met, verified against base with
git show origin/Dev_new_gui:rather than against the diff. So it stayed open, and this delivers the two that were missing — plus the two review findings already filed as #16126.What Changed
Four corrections to
docs/developer/MEASUREMENT_DISCIPLINE.md.#15953 AC4 — instances must arrive with evidence
The document cited 3 issues against roughly 20 described instances. That is assertion wearing the clothes of evidence, and it is the shape the page argues against: a reader cannot check any claim whose source is not named.
Citations added where one was filed —
#15987for both ticked-criterion cases,#16089for js-yaml,#16124for--author @me,#16087for the required-contexts premise. Now 9 unique issues.Where no issue exists, the absence is stated rather than papered over, and it carries information:
#15953 AC5 — the counterweight, and the one I most wanted back
The whole page trains a reader to distrust a low count. AC5 is the case where the low count is right.
Neither is blind. One counts assignments, the other undefined names, and the two they differ on are exactly the two files that bind the name — both correct, about different questions. Reaching for "the lower number is the broken instrument" would have sent someone fixing two files that were already correct.
Without this the document teaches a reflex that is wrong often enough to cause work.
#16126 — family letters run A, B, C, D, F, then E
E was written first and is cited by number on #16100 and #13148, so renaming breaks those. The sequence is now stated where F sits instead of left for a reader to trip over.
On this page above all, a label that does not match what it labels is the subject.
#16126 — Family D was missing its mechanism
D said a correct output can support two causes. It did not say why nobody checks. From the reviewing session's own gate:
The output was correct; the explanation was invented on top of it and went unexamined, because a refusal feels like it has already been investigated. Nobody audits a "no".
That example also draws the line between D and the ladder's rung 2: rung 2 is a guard answering an adjacent question; D is a person answering one on the guard's behalf.
Verification
Docs-only, so the checkable claims are about the text on base:
#15953AC1–AC3 were already verified met on base and are untouched:CLAUDE.md:40links the doc from Never violate,:41carries "name the selector where the result is reported", and:218–:226the known positive.Model Used
Claude Opus 5 (1M context).
Batch rationale
Two issues, one file, one review. #16126's two findings and #15953's two missing criteria are all corrections to the same document, found in the same review pass. Splitting them would put four small edits to one file across two PRs and two CI runs.
Both #16126 findings came from the session reviewing the document, not its author — which is the document's own closing claim arriving as evidence about the document.