/nm: next unmodelled item (FSM leak) — next_leak tool + command - #227
Conversation
The FSM-conformance leaks — open producer PRs the lane classifier buckets into NO modeled state — had a canonical view (human-queue --json's `leaks` array, the dashboard box that should read zero) and no one-call entry point: locating a leak started from the whole org-wide queue render. next_leak (Human profile): the producer-PR enumeration behind that array is extracted into producer_pr_inventory() + leak_scan(), shared by human-queue and the tool, so the two are one computation and the tool answers a PREFIX of the canonical array in its own order — never a parallel search, never a second ordering (#121). The row carries the leak's evidence, both halves: has.producerNote (the trusted note implying a state, truncation flagged) and lacks.aiStateLabel (the classifier's own answer, computed rather than asserted null, the full label list beside it). limit is refused out of 1..=3, never clamped. Empty is the HEALTHY answer and the typed `health` field says so; unlabeled PRs whose comment read failed are counted and named, and a zero over them reports as unproven, never as health. human-queue's own emission is unchanged. nm.md: the command's posture is the issue's three-way split — a leak is a defect to LOCATE, in exactly one of three places, and the deliverable is naming which: the PR's state record (the state it belongs in + the ONE command that files it there), the machine's vocabulary (the missing state + its consuming transition, via the design path), or the classifier (fix the classifier, never the instance; the finding filed as an issue). Written against the post-#219 world: no human:design, no park spelling; a design ruling carries its answer to the producer as the work order. Same LIMIT convention and refusal-relay language as nr.md/ncc.md, same typed-reads / no-shell declaration. human-fsm 0.11.0 → 0.12.0 in the plugin manifest and the marketplace listing (plugin-version-lockstep). Closes #222 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nd set The frontmatter conformance test pins the exact command set the plugin ships (a rename or an unshipped file fails there rather than at install); nm joins the expected list now that nm.md ships. Formatting is cargo fmt's own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 50 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
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 |
…e siblings are listed Three things, all reconciliation with what landed and what CI actually runs. The rust workflow's static job runs `pre-commit run --all-files` after rainix-rs-static, and its `denofmt` hook formats markdown. It skipped locally while nm.md was untracked, so the reflow only surfaced in CI as a red static job. The hook's own output is now committed, and a second run is clean. /nd (PR 226) bumped human-fsm to 0.12.0 for its own command, which is the version this branch had claimed. Two open PRs cannot ship the same version — `/plugin` detects updates by comparing version STRINGS, so the second to land would serve stale content under a version installers have already seen. This goes to 0.13.0, which is past /nd's whichever order the two land in. And the three places that ENUMERATE the human's surface — CLAUDE.md's profile table, README's human-profile paragraph, the plugin README's command table and reads section — now name next_leak and /nm, as /nd named next_design and /nd. An enumeration that omits a shipped tool is wrong the moment its PR lands, and these lists are what a reader consults instead of the tool table. nm.md's "wrong state record" finding also picks up the retired-label case: a label the FSM has deleted lands a PR in this queue exactly as an absent one does. Written as the property rather than naming a label, because the deletion in flight (#225's ai:blocked-deploy) is not the only one that will ever happen and this command should not need editing for the next. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n flight Three open PRs bump human-fsm from 0.11.0 and two of them claimed 0.12.0. `/plugin` detects an update by comparing version STRINGS, so the second of a duplicate pair to land serves new content under a version installers have already seen — the stale-content bug the version-hygiene gate exists to catch. Claims are now distinct and monotonic in merge order: #224 (0.12.0), #227 (0.13.0), this (0.14.0). This PR merges last of the three; landing it earlier means re-bumping past whatever main then carries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ding of the labels The BLOCKER an independent review found, and it is this command's own third finding class turned on the command: the classifier was wrong, so the fix is the classifier and not the instance. `next_leak` and `human-queue` both enumerated leaks as "carries no `ai:*` label". The DEFINITION everywhere else — the tool description, nm.md, CLAUDE.md, README, the dashboard box — is "the PRs `classify_lane` buckets into no modeled state". Those are different sets: `human:*` labels are not `ai:*`-prefixed, so every PR parked in the human-decisions lane satisfied the first while sitting in a perfectly modeled state, waiting on a ruling from the same human reading the leak box. Measured over the pipeline's orgs on 2026-08-06: four of five reported leaks were `human:design` PRs, and the ONE PR genuinely in no state sorted last behind them, below the page cap of 3. At `limit: 1` the tool handed back a PR whose true answer — "no defect, this is waiting on you" — is not one of the three findings nm.md forces a diagnosis into. `counts.leaks` and the dashboard panel read the same array, so they were wrong in the same four places. `is_leak_candidate` now asks `classify_lane` itself, and a `repo_root_tests` pin requires the enumeration to select through it — the `cc_gate` precedent one lane over, where the vetter's flag inbox and the human's are pinned to one classifier for the same reason. A precedence change in the classifier now carries itself into this population with nothing here to update. Beyond the population: - ORDER. The rows arrived in `gh search prs` order, which is newest-first, so the longest-unmodelled PR sank below the cap — on the measured population the oldest leak was also the only real one. `rank_leaks` makes it oldest-first and argues why: a leak is in nobody else's queue, so the harm is how long it sits. `createdAt` rides on every row (and on the dashboard's array) so a human can re-rank a page by eye. - THE FAIL-SAFE IS NOW REACHABLE BY TEST. `leak_scan`'s `unreadable` push had no test at all — deleting it left the whole suite green. It is the only producer of `leakUnknown`, `fetchErrors` and the non-healthy verdict at zero leaks, so losing it would report a run where every comment fetch failed as "healthy — zero leaks". `leak_scan_with` takes the comment read as a seam, and the test drives a total read failure through to the document's own `health`. - THE ROW STATES THE CLASSIFIER'S VERDICT. `lacks.aiStateLabel` was billed as drift detection and was structurally always null, which is exactly why the wrong population was invisible on the artefact. `classifier.lane`/`.state` read `leak`/`leak` on an honest row and name the real state when they do not. - nm.md named `/human-close`, which is not a shipped command. The close path is `/human-fsm:close-candidate <ref> uphold <note>` — it runs `human-close`, resolves PR-or-issue by lookup and needs no pre-existing flag, which is what makes it reachable for a leaked PR. Every filing command is now written in full invocation shape. - nm.md's retired-label property was false: a RETIRED `ai:*` label is still bucketed on purpose, so its PRs never leak. What leaks is a state DELETED from the classifier's vocabulary — corrected, and stated as the property. - README gains the `next_leak` section its siblings each have; the error message is caller-neutral now that two registers consume it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…) into /nm Both deletions land under a PR whose whole subject is "which PRs are in no modeled state", so the interactions are the merge, not a side effect of it. CONFLICT SHAPE: two files, both the plugin version JSONs, both trivial — main carries #224's 0.12.0 and this branch 0.13.0, and mine is the superset (it names /nm) and is already ahead. main.rs auto-merged CLEAN, which is exactly the case that has bitten twice today, so the real work was hunting what the markers could not show. WHAT THE SUITE CAUGHT THAT THE MARKERS DID NOT: - The drift witness in `a_row_carries_the_leaks_own_evidence` asserted a `human:design` PR classifies into the human-decisions lane. #224 deleted that state, so it now classifies as a LEAK and the assertion failed on the merge commit. Repointed at `human:reject` — the lane's one surviving state, and still the live instance of the hazard the field exists for (a `human:*` label carries no `ai:*` prefix, which is what the old population wrongly admitted). - `is_leak_candidate` referenced `RETIRED_BLOCKED_DEPLOY_LABEL`, deleted by #225: a compile error, fixed by dropping the row. WHAT ONLY READING #225's OWN COMMIT CAUGHT — and no test would have: `fdf2ee0` ruled that a PR hand-wearing a DELETED `ai:*` string lands `un-vetted`, not `leak`, because the vetter absorbs it and the verdict that judges it strips the dead label. That ruling was justified by the caller-side `ai_state_label` partition — the exact thing this PR replaced with a classifier-derived population. Under the merge as it auto-resolved, such a PR became a leak again and silently overturned a ruling that landed hours ago. The `lanes_doc` fixture cannot catch it (it feeds `producer_commented` directly), so this is added as a conjunct on `is_leak_candidate` with the ruling cited, plus an assertion over the registry below. It cannot reintroduce the defect this predicate exists to fix: that defect was `human:*` labels parked in a real lane, and the classifier arm is what excludes those. THE THREE PIECES OF COVERAGE THE HUMAN CALLED FOR, so none of the above is re-verified by hand at the next merge: 1. `every_lane_is_reachable_from_some_label_set` — one witness per `Lane`, driven off a new `Lane::ALL`, so an arm going unreachable behind a precedence change is a failure and a lane added later is covered on the day it is added. 2. `DELETED_LABELS` + `a_deleted_label_models_nothing_anywhere` — one property over a registry, replacing the two bespoke per-deletion tests #219 and #221 each shipped. For every deleted label: the ordinary unmodelled fallthrough, dominates nothing, occupies no lane cell (checked across `Lane::ALL`), and no `counts` key names it. The next deletion adds a row of DATA. 3. `lanes_doc_emits_every_state_with_the_right_members` now derives every total from per-row expectations instead of literals. That assertion is the one that read `3` on two branches and was wrong at `4` once both landed, with nothing pointing at it; an expectation beside its input cannot go stale that way. nm.md, the README and the doc comments now state the post-deletion truth: a RETIRED label stays bucketed and never leaks; a deleted `ai:*` label is absorbed as un-vetted; a deleted `human:*` label DOES leak, because the vetter's sweep is `ai:*`-scoped and nothing else claims it. The classifier rule nm.md tells the human to check is now its three real clauses rather than the `ai:*`-only paraphrase. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…) into /nd Conflicts, and how each resolved: - `.claude-plugin/marketplace.json` + `plugins/human-fsm/.claude-plugin/plugin.json` — both sides bumped the plugin. OURS: 0.14.0 stays, distinct from and above main's 0.12.0 (#224) and the 0.13.0 #227 still claims, and the description keeps the third read. - `plugins/human-fsm/README.md` — the whole command table. MAIN's table taken wholesale, because #224 rewrote the `/design` row and resolving toward ours would restore the `human:design` / `--park` prose #219 deleted; the `/nd` row is spliced back into it. Both intents, main's row verbatim. Everything else auto-merged. Main's deletions stand: nothing here reintroduces `human:design` or `ai:blocked-deploy` in any spelling — every remaining mention in the tree is main's own assertion that the deleted state is inert. nd.md needed no correction against merged main: it describes the post-#219 exit (`ai:reject` with the answer as the trusted work order, one call at the head anchor, no parked spelling), and `human-rule … design --rework` now does exactly that. What was aspirational when written is now what the code does. Coverage rather than hand-verification, per the standing call — two hand-written totals near the merged region are now DERIVED from their fixtures: - the withheld-overflow expectation is `raised - ND_MAX_WITHHELD` off a fixture sized from the cap, not a literal `2`; - the row and envelope digit reserves count their numeric fields from the emitted document (`numeric_fields`) instead of a number typed in a comment. That is the exact shape that survives review and breaks on a merge: a count key added on one branch and a reserve typed on another are each correct alone and conflict with nothing when both land. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Reviewed b90d064: approve — read the diff and verified the merge independently. |
#227 landed `next_leak` / `/nm` in exactly the seams `/nd` occupies, so every conflict was the same shape: main's next_leak against this branch's next_design, two independent siblings. Union throughout — nothing of either side is dropped. 18 hunks in main.rs, resolved by taking main's file whole and re-applying this branch's next_design work onto it: a blunt union spliced the two test modules into each other (mismatched delimiters), because the conflict boundaries cut through shared helper context rather than between the modules. What the markers did NOT point at, and the suite did: - `tools.len()` and the narrowing-tool count. BOTH branches bumped 20 -> 21 and 5 -> 6, so git took the identical literal with no conflict at all — and the merged surface has 22 tools and 7 narrowing ones. A hand-written total, individually correct on each side, wrong once both land. - the `nd_population` / archived-set conformance pins landed inside #227's new test at the end of the same module, where `reads` is not in scope. - the shipped-command list is SORTED: the union had to place "nd" before "nm". Versions: 0.14.0 stays — distinct from and above main's 0.13.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Main added two MCP tools and their commands; this branch changes no tool surface, so main's tool table, command lists, plugin manifest and the counts that measure them (22 tools, 7 narrowing) carry over untouched. The one conflict is `lanes_doc_emits_every_state_with_the_right_members`, where both sides replaced the same hand-written totals for the same reason — a literal that is right on each side of a merge and wrong once both land. Main's is the more general mechanism: each fixture row carries its own expected `(lane, state)` and every total is counted off those annotations, so it is kept and used throughout. This branch's two semantic claims are applied on top of it: - the `leak` bucket emits NO lane cell (#130 clarification 2) — its inventory is the top-level `leaks` array, which is what its descriptor declares as its occupancy. Row #14 is therefore annotated `NO_LANE`, the same hand-off #7 already had, and the retirement is asserted both ways: the annotations expect no `leak` cell, and the emitted doc has no `leak` key at all; - the un-vetted total keeps its second, independent reading off the `DELETED_STATE_LABELS` registry beside main's annotation count. The annotations say where each PR lands; the registry says why the bucket is that size, so deleting a state without retiring its label fails here instead of quietly re-annotating itself. `next_leak` is unaffected by the retired lane cell: it builds its rows from `producer_pr_inventory` through `is_leak_candidate` and `classify_lane`, never from `lanes_doc` — which is the property #222's own test pins. The cross-lane total is now counted off the `NO_LANE` annotations rather than written as `prs.len() - 2`, because that subtraction is exactly the shape that survives a merge silently while the fixture hands off a different number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closes #222
/nm— the next unmodelled item for the human to review, fourth sibling of/nr,/nccand/nd(#220). The subjects are the FSM-conformance leaks: open producer PRs the lane classifier buckets into NO modeled state — a trusted🤖 ai:producernote implies a state, noai:*label records one. The dashboard'sleaksbox, the one that should read zero.The
next_leakMCP toolclassify_lane's ownLeakverdict. Issue 222's two clauses — "the same machinery theleaksarray comes from" and "the PRs the lane classifier buckets into NO modeled state" — were in conflict, because the pre-existing enumeration was neither: it was the set "carries noai:*label".human:*labels are notai:*-prefixed, so every PR parked in the human-decisions lane satisfied it while sitting in a perfectly modeled state. Measured over the pipeline's orgs on 2026-08-06: four of the five reported leaks werehuman:designPRs waiting on a ruling from the same human reading the leak box, and the one PR genuinely in no state (rain.flow#475) sorted last behind them, below the page cap of 3 — so at the defaultlimit: 1the tool handed back a PR whose true answer is none of nm.md's three findings.counts.leaksand the dashboard panel read the same array and were wrong in the same four places. The conflict is resolved toward the classifier:is_leak_candidateasksclassify_laneitself, and arepo_root_testspin requires the enumeration to select through it — thecc_gateprecedent one lane over, where the vetter's flag inbox and the human's are pinned to one classifier for exactly this reason. Fixing the population fixes the dashboard too.producer_pr_inventory()(the onegh search prs --authorread, archived withholding per next_close_candidate offers flags from archived repos, where no ruling can be written #206) andleak_scan()(the trusted-comment read overleak_reason) are called by bothhuman-queueand the tool.gh search prsorder — newest-first — so the longest-unmodelled PR sank below the cap; on the measured population the oldest leak was also the only genuine one.rank_leaksorders oldest-first with the argument stated: a leak is in nobody's queue (not the producer's, not the vetter's), so the harm is exactly how long it sits.createdAtis on every row and on the dashboard array.has.producerNote(truncation flagged),lacks.aiStateLabel+ the full label list, andclassifier.lane/classifier.state— the classifier's verdict recomputed live,leak/leakon an honest row. That last field replaces a drift check that could not work:lacks.aiStateLabelwas structurally always null, which is precisely why the wrong population was invisible on the artefact.limitrefused out of range (1..=3, default 1), never clamped, mirroringnext_ready_limit.healthreadshealthy-zero-leaks-every-open-producer-pr-is-in-a-modeled-stateonly at zero leaks over a fully read population. Fail-safe on the other side: candidates whose comment read failed are counted (counts.leakUnknown), named (fetchErrors), and a zero over them reports aszero-leaks-found-but-unread-prs-remain-not-proven-health.leak_scan_withtakes the comment read as an injected seam so that branch is reachable by test — it previously had none, and deleting it left the whole suite green.constassertion that a maximal page plus the withheld list cannot reachMCP_MAX_RESULT_BYTES, adversarial-input test exercising it.narrows: limit; table/profile counts in the drift tests updated (20 → 21 tools, 5 → 6 narrowing).plugins/human-fsm/commands/nm.mdModeled on
nr.md/ncc.md: same LIMIT convention (argument passed verbatim, the binary's refusal relayed rather than rounded), same typed-reads/no-shell declaration, same second-opinion posture. The command's core is the issue's three-way split — a leak is a defect to locate, in exactly one of three places, and the deliverable is naming which:human:design, no park spelling anywhere in the file);The healthy-empty answer is presented as the good outcome it is, with the
leakUnknowncaveat carried alongside.Plugin manifest and the enumerations
human-fsm0.11.0 → 0.13.0, in both the plugin manifest and the marketplace listing (theplugin-version-lockstepgate), with/nmin both descriptions. 0.13.0 rather than 0.12.0 because the sibling/ndPR (#226) claims 0.12.0: two open PRs cannot ship one version string, since/plugindetects updates by comparing versions and the second to land would serve new content under a version installers have already seen. 0.13.0 is past it whichever order the two land in.The three places that ENUMERATE the human's surface now name
next_leak//nm, exactly as #226 namesnext_design//nd:CLAUDE.md's profile table,README.md's human-profile paragraph, andplugins/human-fsm/README.md's command table and reads section. An enumeration that omits a shipped tool is wrong the moment its PR lands. These lines are the expected merge conflict with 226 — resolution is to keep both tools in each list; main gets merged in, never rebased.Merged with main (#224, #225)
Both landed under this PR and both interact with its subject, so the merge is part of the change rather than a rebase over it.
human:design(#224) andai:blocked-deploy(#225) are DELETED; main's deletions won everywhere, and nothing here reintroduces either in any spelling. Conflicts were two files, both plugin-version JSONs, both trivial — this branch is 0.13.0 and remains distinct and ahead of main's 0.12.0.main.rsauto-merged clean, which is exactly the case that has bitten twice today, so the work was in what the markers could not show:a_row_carries_the_leaks_own_evidenceasserted ahuman:designPR classifies into the human-decisions lane. That state is gone, so it now classifies as a leak and the assertion failed on the merge commit. Repointed athuman:reject, the lane's surviving state.is_leak_candidate's test referenced the deletedRETIRED_BLOCKED_DEPLOY_LABEL.fdf2ee0ruled that a PR hand-wearing a deletedai:*string landsun-vetted, notleak— justified by the caller-sideai_state_labelpartition that this PR replaces. As auto-merged, such a PR became a leak again, silently overturning a ruling that landed hours earlier.is_leak_candidatenow carries that ruling as an explicit conjunct with the reasoning recorded, and the registry property below pins it. It cannot reintroduce the defect this predicate exists to fix: that defect washuman:*labels parked in a real lane, which the classifier arm excludes.Three pieces of coverage so none of that is hand-verified next time (the human's call — the checks themselves become tests):
every_lane_is_reachable_from_some_label_set— one witness perLane, driven off a newLane::ALL, so an arm going unreachable behind a precedence change fails, and a lane added later is covered on the day it is added.DELETED_LABELS+a_deleted_label_models_nothing_anywhere— one property over a registry, replacing the two bespoke per-deletion tests RULED: an answered design question routes straight to producer rework, same as a rejection #219 and RULED: migrate the ai:blocked-deploy residue to ai:reject — rework each PR for the split release lifecycle #221 each shipped. Per label: the ordinary unmodelled fallthrough, dominates nothing, no lane cell (checked acrossLane::ALL), nocountskey. The next deletion adds a row of DATA.lanes_doc_emits_every_state_with_the_right_membersderives every total from per-row expectations instead of literals — that assertion is the one that read3on two branches and was wrong at4once both landed, with nothing pointing at it.The docs now state the post-deletion truth: a RETIRED label stays bucketed and never leaks; a deleted
ai:*label is absorbed as un-vetted; a deletedhuman:*label DOES leak, because the vetter's sweep isai:*-scoped and nothing else claims it.Coordination
Sibling work in flight in this same file: #219, #130, #220, #221. This PR scopes to
next_leak+nm.md+ the manifest bump; on conflict, main gets merged in.QA
next_leak_tests::{the_leak_population_is_the_classifiers_own_verdict_not_a_label_spelling, a_failed_comment_read_is_unknown_and_never_a_clean_bill, the_leak_queue_is_oldest_first_and_the_page_is_a_prefix_of_it, the_page_size_defaults_to_one_and_is_refused_outside_its_range, a_row_carries_the_leaks_own_evidence, an_oversized_note_and_label_list_are_clipped_and_say_so, an_empty_queue_is_the_healthy_answer_and_says_so, a_populated_queue_reports_leaking_and_what_the_page_left_behind, a_maximal_page_of_adversarial_rows_still_fits_the_budget, the_fixed_allowances_cover_a_row_a_withheld_entry_and_an_envelope}plusrepo_root_tests::the_leak_population_is_derived_from_the_lane_classifier. Each fails on base because the functions they exercise do not exist there (the suite does not compile at base); the mutation table below shows each failing the moment its behavior is broken while the rest stay green. The two population tests are the BLOCKER's own regression: revertingis_leak_candidateto theai:*-label rule fails both. Full suite on the branch: 1013 passed / 0 failed in the main binary (+3/9/47/8/7/4 integration), up from 1010 — the three new tests are the population, the fail-safe seam and the ordering.is_leak_candidate→ai_state_label(labels).is_none()(the exact pre-existing defect) → killed bythe_leak_population_is_the_classifiers_own_verdict_not_a_label_spelling+ therepo_root_testspin; candidate filter →if true→ killed by the pin; dropunreadable.push(the sole survivor of the previous pass) → killed bya_failed_comment_read_is_unknown_and_never_a_clean_bill;leak_queue_healthignoresunreadable→ killed by that test +an_empty_queue_is_the_healthy_answer_and_says_so; droprank_leaks→ killed; reverse the comparator to newest-first → killed bythe_leak_queue_is_oldest_first_…; hardcodeclassifiertoleak/leak→ killed bya_row_carries_the_leaks_own_evidence; clamp the limit → killed; blankproducerNote→ killed; lie onproducerNoteTruncated→ killed; drop the note clip → killed (incl. the budget test); zero themorearithmetic → killed; blankcreatedAt→ killed.next_ready's prefix property,next_close_candidate's deliberate-and-argued ordering,cc_gate's one-classifier pin); and hand-built fixtures whose expected JSON is written out literally, independent of the builders. The live population was verified twice against the binary's own search args before and after the fix.next_leakMCP tool off the same leak-detection machinery with typed result, refused limit, evidence rows, truncation flags, healthy-empty answer; (2)nm.mdon the nr/ncc model with the given frontmatter, LIMIT convention and three-way defect-location posture in post-RULED: an answered design question routes straight to producer rework, same as a rejection #219 vocabulary; (3) plugin version bump — covered (1), (2), (3). Also fixed, in scope because it IS the issue's own third finding class turned on this code: the leak population, the queue order, and the untested fail-safe. Not covered by design: the sibling PRs' scopes (RULED: an answered design question routes straight to producer rework, same as a rejection #219, human-queue --json emits counts but not the state vocabulary, so consumers hand-copy it and drift silently #130, /nd: next ai:design item to rule on — next_design tool + command, sibling of /nr and /ncc #220, RULED: migrate the ai:blocked-deploy residue to ai:reject — rework each PR for the split release lifecycle #221).cargo test(1013+78 green); CI-exactnix develop github:rainlanguage/rainix/53e96a7…#rust-shell -c rainix-rs-static(rustfmt --check + clippy-D warnings -D clippy::all, changed file touched first) exit 0; fullpre-commit run --all-filesbundle clean and idempotent on re-run (denofmtis what made the first static job red);nix build .#pr-review-reportexit 0, which runs the release-profile suite inside the derivation.next_readyencodes and this PR should not benefit from the ambiguity.🤖 Generated with Claude Code