Repository navigation
chore(skills): review PRs through angles and whole rounds - #1522
Merged
Merged
Conversation
The review skill ran fixed passes out of one reference file already at its word cap, and nothing in it drove a review to finish in one round. Passes sampled what they checked, fixes were written before they were weighed, and later rounds kept finding what the first should have. The skill is now an orchestrator of review angles. Each angle is a reference saying what it attacks, which skills it loads and the matrix its report fills: correctness, fidelity, determinism, robustness, contract, design, reuse and maintainability, testing, performance, developer experience, consistency, and claims and process. A round runs every angle over the whole change, deep into its logic and broad over the code living with it, however much it finds first. rounds.md holds how a round runs: the setup, now also before a PR exists and with no origin; CI's run as the gate; every decision resting on the vision it serves and a run showing it holds; a fix designed before it is written; and a first round that finds everything, with a second, by a reader the first did not anchor, that confirms the fixes. The existing rules move into the angle they serve, their text unchanged bar the few the new structure rewords, and each new rule cites the work that showed its failure. morphic-designing-code gains rules for sharing one implementation and keeping domain-free code apart. The shipping skill runs the first round before a branch's first push, morphic-verifying-changes defines done by it, and CLAUDE.md's review line runs the second round once the PR opens.
morphic-verifying-changes gains the rules its probes kept missing. A mutant run owns its cache and stops before the disk fills, a kill counts only from a test that reaches the plant, and a claim about what a check leaves out is planted where only the excluded callers go. A full disk or a removed cache reads as a failing build, a gate failure under load is told from one the change caused, a test's go children never reach a go wrapper on PATH, and a cache probe holds the whole environment fixed, which replaces the rule naming GODEBUG alone. A test raises a time limit's outcome through a seam, an absence is asserted on the field that would hold it, a new gate target draws a finding planted for it, a lint probe lists every finding, and a count over a whole-program analysis takes a fixed input set. The gate is answered by CI's run on the final head as well as by a local run, in CLAUDE.md, morphic-verifying-changes and the styleguide departures alike.
morphic-measuring-performance's readings misled in ways no rule named. An instruction count stops at the timed process, so work in children reads as free. A count holds only across two rounds and beside a control build. A resident set read with the collector off is total allocation. Statement counts per function find where a small difference comes from, and an instruction count confirms each site. A loop that reruns a phase until it settles is driven through many turns, at n and 2n, with its budget sweep rerun past the first turn. The common path is priced on a spec small enough to hold uncollected, the golden spec answering only a claim of a large effect, in the skill's claim table and in the review's price-common-path alike. A counting seam is the one the code already has: a pure function's parameter, or a type's field where a type does the work.
morphic-designing-code gains four rules from work its table let through. A visitor of a type few nodes carry prunes the walk to them, with a test on a carrier off the path and a counting seam, and the table sends a document walk to it beside read-once-per-run. Each part of a bound's charge is grown alone against the cost it stands for. A new recursion under compilers/openapi joins the recursion pin with its bound. A function one package hands another stays a function only for I/O, a policy, a live query, a substituted seam or a callback, and otherwise becomes the data the caller holds; the table gains its row.
The version-collision rule's heading and body read two ways, and it named one part as conflicting where any of the constant, the row and the entry can merge silently. It now says the PR merging second takes the next version, and a check after each merge finds a repeated version, the SKILL's bullet moving to merge time with it. A new TypeID position is also read against the lists of references the design documents give, a declaration's form reads only what an additive change leaves alone, and a predicate over a property Unicode publishes is swept over every code point beside its witnesses.
The push checklist read every commit back to origin/main, so a stacked branch reported its base PR's subjects as its own, and one that had left a stack read the stack's commits too. It now reads the branch's first-parent line against the branch it targets, and subjects.py takes a repeatable --base for the target and a former base, with tests. The push names the PR's branch, so it runs from a detached review worktree, and CI is read after it knowing a conflicting PR gets no run. New rules read each issue a PR closes whole, comments and out-of-scope items included, and again before saying it closes; send an edited body only when its fetch produced it; count a cap two open PRs share at each head; merge a landed stacked base's final head before main; replay a branch's own diff onto main to leave a stack; and state that the repository's no-attribution rule overrides a harness's reminder.
The review setup routed a review with no origin, and one before its PR exists, only after the fetch it warns against, and called the pre-push tree the author's own worktree. It now opens with those cases, a check that no other checkout holds work on the PR's branch, and the route for a stacked base that has landed; a mechanical conflict is resolved in the throwaway tree rather than aborted. The gate rule says an unpushed branch has no run yet, and the first round keeps its probes in a script for the second. The sentence on deliberate oddities, lost when the skill was split, becomes a rule: only a comment at the line excuses one. A restructured document accounts for every sentence it held. Claims and process runs each command an edited rule prescribes, reads closed issues by the shipping rule, and checks a choice resting on an open issue against the open PRs settling it. Correctness simulates the runs a CI or cache change claims, robustness re-measures a budget's stated margin when its charge widens, and a near miss is taken from each class of keyword a predicate tells apart. The styleguide skill's trigger names the angles that load it, and a misquoted name, a first-person phrase and unwrapped lines are fixed.
skills_lint held a grep pattern holding a slash, a git ref and a refspec to the tree as missing paths, so probes were weakened to pass it. A word holding a pattern's |, ^ or \, or a colon other than a :line suffix, now names no path, and a span starting refs/ is a git ref. Over the current skills no word the lint held as a path changes. A rule cited by its key alone passed whatever key it named; the lint now refuses that form and names the full one. A scripts/ or references/ path is held to the skill's own directory first and then to the repository, which keeps a scripts/ of its own. Each fix has a test that fails when the fix is reverted.
morphic-checking-style listed a chapter's rules by heading and sent a reader to a rule's body only where a line already looked like a breach, so a breach the heading does not suggest passed. Each listed rule is now read to its Enforcement line before lines are held to it. The departure exempting an unexported type from a compliance assertion now holds only where a call's parameter is the interface; an optional interface, found by a run-time assertion, gets a departure of its own, converting the type where it is passed. morphic-openapi-compiler gains a rule for a change to how a JSON Schema dialect reads: count the committed corpus for the construct, then measure on standalone schemas of the dialect and the test suite's groups for it, each reached through a 3.1 wrapper, reading the type a $ref lands on as well as the diagnostics.
Each rule added for the open skills issues is now cited from the review angle that applies it, so a review, and an author's first round before a push, reach it by name: mutation and plant rules from Testing, measurement rules from Performance, a charge's parts from Robustness, and a shared cap and a fetched body from Claims and process. Reading the closed issues whole showed three out-of-scope items naming work no issue tracked; each is now an issue of its own and named where its rule lives. closing-issue-read-whole carries only the items naming work still to do. A stale local linter's export-data failure gets the toolchain rule its readers kept rediscovering.
The push checklist's artifact grep had been narrowed to the branch's first-parent commits, which drops a merge commit's body and anything merged from another branch, though a default squash pastes each one. It now reads every commit the base and main lack; the subject check keeps the narrower reading. A push from a detached tree with no PR stops on an empty branch name. A contract step had kept the version-collision reading the rule had just settled, the rule's probe named history headings the file does not have, and a departure's probe used \w, which git grep -E does not take here, so it missed a second site. Whys that rested on open PRs cite the issues recording the same evidence, the landed-base rule carries the resolution its issue's comments record for main's later conflicts, and the attribution rule gains its probe. skills_lint holds a file:line:column span to its file, which main read as a missing path and the pattern fix had stopped holding at all. The IR version document no longer says the second branch always meets a conflict. The angle intros are rewrapped to the width the rest keeps.
closing-issue-read-whole carried only an issue's out-of-scope items to an open issue, while #1473 deferred a configuration change in its Direction instead, which a second review round found unrecorded. A deferred alternative naming work still to do now goes to an open issue the same way.
Six issues this branch closes named an existing rule as lacking a lesson, and each lesson went into a new rule beside it that the named rule never cited: instructions-not-wall-clock (#1294, #1362), count-on-one-thread (#1495), bound-the-product (#1461), edit-pr-body-from-live-copy (#1326) and read-once-per-run (#1348). A reader sent to the named rule met none of them, so each issue's title still described its rule. Each named rule now cites the new one, inside its 150 words. The curating skill's rule format now says a rule split in two cites the second from the first, and closing-issue-met-at-its-site has a review hold each closing issue's title against the site it names on the head, and each step of its Direction against the line meeting it.
gate-failure-under-load reran each failed package alone but never the gate steps after the failure, which make gate never reached, so a load failure left their verdict unknown while the reruns read as clean. #1347 asked for those steps to run after the reruns; the rule now says so.
The lint read a colon before anything but :line or :line:column as no path, so a span citing a range such as file.go:12-20 went unchecked, and a renamed file cited that way would pass. A path's line suffix is now one grammar, a line, a line and column or a range, which both the stripping and the not-a-path test read, so the two cannot drift. The pattern's own :( alternative, which the colon rule already covers, is gone. subjects.py refuses an empty --base before git runs, but git refuses one too with the same exit status, so the test passed with the check removed. It now asserts the check's message.
Three paragraphs this branch edited were left unwrapped, one of them at 148 columns in docs/ir/ir-version.md, and are rewrapped to the file's width. interface-assertions-stay-narrow cited optional-interface-converted right after "since the call fails the build", which read as support for that sentence; it is the case the build cannot hold, and the rule now says so where it cites it.
Two asks in the closing issues' comments had no home. #1347's: gates that keep failing under load run one at a time from one queue, never after a pgrep check, which matches any command line holding the words and races another start. queue-gates-one-at-a-time says so, cited from gate-failure-under-load, which is at its word cap. #1427's: a review learns its stacked base has landed from the base PR's state and mergedAt, as a baseRefName read before the retarget still names the deleted branch. The review setup now says so beside the landed-base rule it sends to.
The push checklist's artifact greps read $pat. Run in one chain whose earlier step failed, as a fetch on a dropped connection does, pat was never set and grep -niE "" matched every line of the log and the diff, so a hundred kilobytes of hits hid any real one, and the push after it still ran. It happened twice, on #1435 and on this branch. The greps now read ${pat:?}, which stops them with an error naming pat.
The lint's fallback from a skill's own references/ or scripts/ to the repository's reported a skill path git ignores as one that does not exist, where main said no clone holds it. When neither holds the path, the reason given is now the skill's own. Three readings had no case to fail on: a colon before a port, as in localhost:8080/v1, which the line-suffix grammar must read whole rather than as a :line, a bare #key of one word, and a script both the skill and the repository hold, which #1363 asked for. Each now has one.
disprove-each-finding had a review clear a finding by a decision in
.golangci.yml's exclusions or the tracker, while the oddity-needs-a-comment
rule it cites said only a comment at the line excuses one. The oddity
rule now accepts a lint finding's exclusion with its reason beside it,
where CLAUDE.md puts a suppression, still refuses the tracker alone, and
disprove-each-finding defers to it.
The push checklist ended in `[ -n "$h" ] && git push`, which ended the
chain with exit 1 and no message when it found no branch to push to, as
in a detached worktree before the PR opens. It now pushes to
${h:?name the branch}, which stops with that message, and
review-own-fixes points at the checklist rather than spelling the push
another way.
own-commits-against-the-base now scopes a former base's exclusion to
the subjects, as the artifact grep keeps those commits' messages, and
send-only-what-the-fetch-produced writes out the gated command its
probe runs.
CLAUDE.md's line on reviewing a new PR lost, in this branch's rewrite, the clause sending a review back over its own fixes. It now runs the next round on them until one finds no issue or nit, as first-round-finds-everything already says. python-plant-without-bytecode: a planted Python file runs with -B from a copy holding no __pycache__, as CPython reuses a cached .pyc while the source's size and modification second match, so a plant of the same size written within that second is never read and reports the last plant's verdict. The review's Testing angle cites it.
lint-probe-lists-every-finding had a probe pass --max-same-issues=0 to see every finding, but golangci-lint also stops at fifty findings of one linter by default, and says nothing of the rest: sixty planted os.Remove calls drew three errcheck findings by default, fifty with that flag and sixty with --max-issues-per-linter=0 beside it. The probe now lifts both caps. analysis-input-is-fixed's probe also diffs a result against one rooted at production's entries alone, as #1506's comment asked.
The comment over generations said that whichever of two changes claiming one version merges second meets the other's row in a conflict. Two branches claiming 0.30.0 merged clean into two rows of it (#1378), as docs/ir/ir-version.md now says, so the comment says the same: whichever merges second checks for a repeated version.
ci-is-the-gate limited a review's local runs to probes, mutants, differentials and measurements, while no CI runs the skills lint or the scripts' tests, so a review of a skill change had no rule running them. It now names both. moved-prose's awk probe flagged every SKILL.md's closing front-matter line as markup opening after prose. It now skips the front matter, and still flags a list line after a paragraph.
python-plant-without-bytecode credited -B with a fix a copy free of __pycache__ also needs, as -B writes no bytecode but still reads stale bytecode left behind; its Why and Probe now say both. The heading of count-stops-at-the-timed-process names /usr/bin/time, whose count the rule measured, rather than every instruction count. subjects.py's test of a former base passed its two bases in one order only, so keeping the last base alone passed every test; it now runs both orders.
subjects.py read a branch's own commits against --base alone once one was given, so a branch started on a main that had moved past its base, then stacked on that base, counted main's newer commits as its own and held their subjects to its PR, while the checklist's artifact grep beside it excluded both. It now reads against origin/main as well as every --base, as no commit main holds lands again, and a test holds that branch shape. own-commits-against-the-base names both, and its probe leaves merges out, as the subjects do, so it matches the count subjects.py prints.
The lint's fallback to a repository path normalizes it, and no test held that: a span such as scripts/./fuzz.sh passed with the call removed only because nothing cited one. The repository-script test now does. python-plant-without-bytecode now runs the unplanted copy beside a plant, by mutation-controls, as a test reading files beyond a copied scripts/ fails in every copy and would read as each plant's kill.
The lint refused a rule cited by its #key alone only in a one-word span, so `see #key` in a command or #key in prose passed, as #1344 reported of every bare citation. Both are now refused, outside a SKILL.md's frontmatter, where # opens a YAML comment, and outside a link's target. A test also cites a script through scripts/../, which the skill-path normalizing now has a case for. subjects.py refused an empty --base, but the checklist passes origin/<base>, which a failed gh pr view leaves as origin/. That is refused too, naming why.
optional-interface-converted dropped the `var _` that #1266 offered beside a conversion, which archtest accepts; it names both again. Correctness names morphic-curating-skills as the domain skill of a change to .claude/skills, which no angle loaded, and a line orphaned by an earlier edit to disprove-each-finding is rewrapped.
This was referenced Nov 5, 2026
OmarAlJarrah
added a commit
that referenced
this pull request
Nov 6, 2026
The departure's Rule and widened-field-values' Probe each gained a line past the 100 columns their files wrap at, where no code span forces it, and both are rewrapped. The Why of later-rounds-read-what-moved read #1522's figure of about 240,000 tokens as what a round spent, where it is the context each reader ended holding. The Why argues where the findings sat, so the figure goes.
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.
Summary
Two changes to
.claude/skills, plus the lines ofCLAUDE.md,docs/ir/ir-version.mdand a comment inir/irversion_test.gothey touch.skills:issue is fixed, each in the skill whose trigger fires when its lesson applies.The review skill
The skill ran fixed passes out of one reference file already at its word cap. Each pass sampled what it checked, and nothing asked on its own about testing adequacy, performance, reuse or consistency. Fixes were written before they were weighed, and later rounds kept finding what the first should have.
SKILL.mdis now a table of angles. Each angle is a reference under.claude/skills/morphic-reviewing-prs/references/that says what it attacks, which skills it loads and the matrix its report fills, every cell with a run or a reason:mainIRVersion, diagnostic codes, the CLI, the Go APImain, in time and memoryreferences/rounds.mdholds how a round runs:Round 1 now runs before a branch's first push (
morphic-shipping-prs), andCLAUDE.md's review line runs round 2 once the PR opens.morphic-verifying-changesdefines done by round 1.The old
references/review-probes.mdrules move into the angles they serve. Five are reworded for the new structure:code-before-claimsgives its mutation half toplant-beyond-the-listed-mutants;fan-out-a-pass-to-a-readerbecomesfan-out-an-angle-to-a-reader;mechanism-existswidens to helpers, algorithms and libraries;read-standing-reviewsandreview-own-fixesspeak of angles.The old skill's sentence on deliberate oddities becomes
oddity-needs-a-comment.The open skills issues
Each issue becomes a rule or the edit it asks for, cited from the review angle that applies it.
morphic-verifying-changes:pgrepcheck (skills: no rule tells a gate failure under load from one the change caused #1347);gochildren never reach agowrapper onPATH(skills: a go wrapper on PATH never sees a test's go children #1443), and a cache probe holds the environment fixed (skills: the test cache keys on PATH, and toolchain.md names only GODEBUG #1444);morphic-measuring-performance:morphic-designing-code:morphic-changing-the-ir:TypeIDposition is read in the documents' lists of references (skills: a new TypeID position is swept through its code readers alone #1303);docs/ir/ir-version.mdno longer says the second branch always meets a conflict, which skills: the version-collision rule names the wrong part as conflicting #1378 showed false.morphic-shipping-prs:mainand the branch it targets, withsubjects.py --baseand tests (skills: the push checklist reads a stacked branch's base commits as its own #1341);morphic-reviewing-prs:origin, a branch before its PR exists (skills: the review setup assumes an origin and an open PR, and skips review-without-origin #1343), another checkout holding the branch (skills: the review setup does not check for another checkout holding the PR's branch #1328) and a landed base, read from the base PR's state (skills: a review merging main after a stacked base squash-merged conflicts at the base's own hunks #1427);CLAUDE.md,morphic-verifying-changesand the styleguide departures (skills: a review's gate pass cannot leave a head behind main to CI #1286): the gate is answered by CI's run on the final head as well as by a local run. Every one of the issue's sites now says so.go testover the touched packages on the merged tree. The review runsgo build ./...there instead, and leaves the suites to CI oncemainis merged in, as the issue's later comments record a maintainer asking.morphic-checking-style:morphic-openapi-compiler: a dialect's reading is measured on standalone schemas of that dialect (skills: no rule says where a dialect's reading meets real input #1503).skills_lint.py, with tests:file:line:columnspan is still held to its file (skills: the lint reads a grep pattern holding a slash as a missing path #1317);#keycitation is refused (skills: skills_lint passes a bare #key citation whatever key it names #1344);scripts/path falls back to the repository's own (skills: skills_lint reads a repository-root scripts/ path as the skill's own #1363).A review of the branch at
78c30a744found five rules a closing issue named as lacking a lesson that never cited the new rule the lesson went into, and two asks in the issues' comments with no home. This PR now also:morphic-curating-skillssay a rule split in two cites the second from the first;closing-issue-met-at-its-siteinmorphic-shipping-prs, cited from the Claims and process angle);file.go:12-20, to its file, through one grammar for a line suffix that the stripping and the not-a-path test both read, and drops a pattern alternative the colon rule already covers;subjects.py's empty-base check, which git's own refusal of an empty ref masked;optional-interface-convertedfrominterface-assertions-stay-narrowon the case it covers;${pat:?}, so a pattern an earlier failed step left unset stops them with an error rather than matching every line, as it did on fix(compilers/openapi)!: read binary idioms as file content #1435 and on this branch's own push.A fresh reader's review of
29372a248found six more nits and a trap in planting Python. This PR now also:oddity-needs-a-commentaccept a lint finding's.golangci.ymlexclusion with its reason, whereCLAUDE.mdputs a suppression, anddisprove-each-findingdefer to it;review-own-fixespush through it;send-only-what-the-fetch-produced's gated command, and scopesown-commits-against-the-base's former-base exclusion to the subjects;python-plant-without-bytecode: a planted Python file runs with-Bfrom a copy holding no__pycache__, as CPython reuses a stale.pycfor a same-size plant written within one second;CLAUDE.md's review line the clause running the next round on a review's fixes, now until one finds noissue:ornit:.A fresh reader's review of
3b4d18424found one more defect, that golangci-lint caps a linter's findings at fifty as well as a text's at three, and five nits. This PR now also:lint-probe-lists-every-findinglift both caps, with--max-issues-per-linter=0beside--max-same-issues=0;analysis-input-is-fixed's probe diff a result against one rooted at production's entries alone (skills: hold a whole-program analysis to one input set before counting over it #1506);ci-is-the-gaterun the skills lint and the scripts' tests, which no CI runs, andmoved-prose's probe skip a file's front matter;python-plant-without-bytecodethat-Bneeds a copy free of__pycache__, and names/usr/bin/timeincount-stops-at-the-timed-process's heading, the count it measured;generationscomment inir/irversion_test.go, which still said two claims on one version always conflict (skills: the version-collision rule names the wrong part as conflicting #1378);subjects.py's two bases in both orders.A fresh reader's review of
b4795b61afound thatsubjects.py, given a--base, stopped reading againstmain, so a branch started on amainthat had moved past its base, then stacked on it, countedmain's newer commits as its own; and three nits. This PR now also:subjects.pyread a branch's own commits againstorigin/mainas well as every--base, with a test of that branch shape, andown-commits-against-the-basename both and leave merges out of its probe, which then matches the countsubjects.pyprints;scripts/./fuzz.sh;python-plant-without-bytecoderun the unplanted copy beside each plant, bymutation-controls, as a test reading files beyond a copiedscripts/fails in every copy.A fresh reader's review of
6ba7470c9found no defect that breaks anything, and three nits. This PR now also has the lint refuse a bare#keyin prose and in a command, outside frontmatter and link targets (#1344), keeps #1266'svar _option inoptional-interface-converted, refuses anorigin/base whose name a failedgh pr viewleft empty, and has Correctness loadmorphic-curating-skillsfor a change to.claude/skills.Four items in the closing issues, left out of scope or deferred, named work no issue tracked. Each is now an issue, cited where its rule lives:
ir.WalkValuesshould find a cycle visitor by a run-time assertion;check-lint-versionshould fail;make lintshould list every finding of one text, which skills: no rule says golangci-lint reports three findings of one text by default #1473 deferred.Open PRs editing the same files, for whichever lands second to lint on the merged tree:
cost-tests.md,toolchain.md,morphic-measuring-performance'sSKILL.mdandCLAUDE.md;toolchain.mdandCLAUDE.md;departures.mdandCLAUDE.md;CLAUDE.mdanddocs/ir/ir-version.md;CLAUDE.md;ir/irversion_test.go, where each appends rows well below the comment this PR edits.Closes #1262
Closes #1263
Closes #1265
Closes #1266
Closes #1270
Closes #1285
Closes #1286
Closes #1294
Closes #1303
Closes #1306
Closes #1308
Closes #1317
Closes #1326
Closes #1328
Closes #1338
Closes #1341
Closes #1343
Closes #1344
Closes #1346
Closes #1347
Closes #1348
Closes #1352
Closes #1357
Closes #1358
Closes #1362
Closes #1363
Closes #1364
Closes #1374
Closes #1378
Closes #1380
Closes #1392
Closes #1427
Closes #1443
Closes #1444
Closes #1445
Closes #1454
Closes #1461
Closes #1462
Closes #1473
Closes #1476
Closes #1477
Closes #1493
Closes #1495
Closes #1503
Closes #1505
Closes #1506
Closes #1507
Closes #1510
Closes #1511
Closes #1520
Test plan
python3.14 .claude/skills/morphic-curating-skills/scripts/skills_lint.py→ clean.python3.14 -m unittest discover -s .claude/skills/<skill>/scripts→ OK formorphic-curating-skills,morphic-shipping-prsandmorphic-verifying-changes, all on the tree merged withmainatab953d453.subjects.pyreadingorigin/mainalone fails the three--basetests, and reading the--basealone, withoutorigin/main, failstest_mains_own_commits_are_never_the_branchs;file:line:columnfix;test_a_pattern_or_a_ref_in_a_span_names_no_pathreverted, without ranges, or with the stripping and the not-a-path test reading two grammars;subjects.py's empty-base check failstest_an_unknown_or_empty_base_exits_two;test_a_path_git_ignores_is_held_as_no_clone_has_it, and a line suffix read without its end or a bare key required to hold a hyphen each fails its own case.CLAUDE.md:main's lint, run there, reports no finding the branch's does not, and the line-range grammar reads each of 2,337 distinct span and code-block words as78c30a744's lint did.review-probes.mdat4ac3031d7, compared with its new home after mapping citation paths back: 27 of 36 are word for word. The five above differ for the new structure, and four for other changes on this branch:near-miss(skills: near-miss names only annotation keywords as a predicate's near misses #1507),price-common-path(skills: the common-path cost row sends a small claim to a reading too wide to show it #1308),disprove-each-finding, which now defers tooddity-needs-a-comment, andmoved-prose, whose probe now skips front matter.SKILL.md.subjects.py --baseand the push by name (--dry-run);gh pr view <N> --json mergeable,statusCheckRollup;go run ./cmd/morphic-harnesson a sample spec;make check-lint-version;main: only 0.3.0 and 0.4.0, which repeat by design);replay-own-diff-onto-mainin a scratch repository, whose merge then differs frommainin the PR's own files alone, withmainas its second parent;pgrep -lf 'make gate'beside a shell running no gate, which it lists, andgh pr view 1459 --json state,mergedAton a landed stacked base;go test'sPATHprefix and its cache keying onPATH, in a scratch module;patunset, which stops with an error underbashandzshalike, and the push with no branch, which does the same;send-only-what-the-fetch-produced's command, which stops at the fetch for PR 0 and passes its gates for this PR;.pycprobe, which reads the first of two same-size writes twice without-B.a5cc10441: 9 nits and a question, fixed incaafbe732.966bb129e: 2 issues, 7 nits, 3 questions and a suggestion, fixed inec2252dd8. The questions were answered by the landed-base rule's resolution step, lint: decide whether make lint lists every finding of one text #1526 and their-version.mdfix.78c30a744: 5 nits and 2 suggestions, fixed in969ee8300to4a0a39b2aand in this body's count above, and the two comment asks above, fixed incd7e51109; the checklist's grep guard followed in29372a248. Each script fix was seen to fail its test reverted, and each commit passes the lint and the scripts' tests on its own.29372a248: 6 nits and 2 suggestions, each reproduced before it was fixed, inb5d2f7a45to3b4d18424, with the loop clause above. Of the suggestions, showing a former base in the checklist's block is left out, as an optional[--base <tip>]there reads as a shell redirect when copied; the rule's scoped sentence carries the case.3b4d18424: 1 issue and 5 nits, each reproduced before it was fixed, indd99baa82tob4795b61a, and a question onperf statsettled by naming/usr/bin/timein the heading. golangci-lint over sixty plantedos.Removecalls gave 3, 50 and 60 findings by default, with--max-same-issues=0and with both flags; the two-base test, with one base kept, fails in one order; and the front-matter probe passes the PR's files and flags a list line after prose.b4795b61a: 1 issue and 3 nits, each reproduced before it was fixed, in64d3c9351and6ba7470c9. Each fix's planted defect fails its test beside an unplanted control, andgit rev-list --count --first-parent --no-merges HEAD --not origin/maingives 25 onb4795b61a, the countsubjects.pyprinted there.6ba7470c9: noissue:, 3 nits and 2 suggestions, fixed in85d3b1311and03acbbc24; each fix's planted defect fails its test beside an unplanted control.