Close-candidate flags cover both subject types, one upheld inbox, close is decide+do - #215
Conversation
…se is decide+do The flag lifecycle is one machine whatever carries the label (#211): the flagged population is now both gh search nouns behind one argv builder, the vetter's unvetted inbox and the human's upheld inbox both mix issues and PRs, and record-close-candidate-verdict judges a producer flag on a PR exactly as on an issue — refusing only the PR whose label is the vetter's own close verdict, which lands in the same single upheld inbox (#212) instead of a PR lane state; classify_lane hands every flagged PR to the flag machinery so no subject sits in two states at once. A close ruling is decide+do with no state between (#213): the ruling vocabularies offer no close verb, human-close writes the pinned comment, closes, then retires the flag, and every tear lands where machinery finishes it — an open flagged subject with a recorded close ruling is completed by the vetter state-load (CcGate::TornHumanClose), a closed subject still flagged is swept by the same state-load's closed-side search, and an open unflagged one resumes on re-run via the comment dedup. Closes #211 Closes #212 Closes #213 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ctor reads the ruling word FLAG_SEARCH_NOUNS is the single noun list every flagged-population enumerator iterates (open-side fetch, closed-side sweep, and the tests), so the prs half cannot silently drop out of one of them; human_close_ruled gains the test that a recorded keep-open — whose anchor also spells "close-candidate @" — never reads as a torn close the completion would execute. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 49 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 (5)
WalkthroughThe PR removes ChangesUnified close-candidate workflow
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Human
participant human_close
participant GitHubSubject
participant Labels
Human->>human_close: submit close decision
human_close->>GitHubSubject: post pinned ruling comment
human_close->>GitHubSubject: close issue or pull request
human_close->>Labels: retire ai:close-candidate
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/human-fsm/commands/close-candidate.md`:
- Around line 29-35: The close-candidate documentation must distinguish the two
PR cases: update the reject section in
plugins/human-fsm/commands/close-candidate.md (lines 29-35) to document
producer-flag PRs being rejected to unvetted and vetter-owned PR close verdicts
being sent to human-close, including both commands; update the adjacent
population invariant in CLAUDE.md (lines 359-370) to make the same distinction
between producer flags and vetter-owned close verdicts.
In `@README.md`:
- Around line 117-122: The transition documentation for human-close currently
lists the operations in the wrong order. Update the human-close row in README.md
and the matching transition table in CLAUDE.md to document ruling comment,
close, then retirement of ai:close-candidate, matching the terminal-edge
recovery model.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d196dbb8-bafd-42e7-88f8-a482cb2a644b
📒 Files selected for processing (6)
CLAUDE.mdREADME.mdcampaign-prompt.txtplugins/human-fsm/commands/close-candidate.mdpr-review-report-rs/src/main.rsreview-prompt.txt
The three markdown files this branch edited take the denofmt reflow the rainix pre-commit bundle enforces, and the plugin content change is a release: plugin.json and the marketplace entry move to 0.11.0 together. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The human-close rows in both transition tables now state comment -> close -> retire (the order the machinery is built around), and the reject/population prose distinguishes a producer flag on a PR (judgeable; reject returns it to the vet queue) from the vetter's own close verdict (the human's, refused by the flag verdict) instead of collapsing the two PR cases into one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Reviewed d86235a: ready to merge. Independent read of the head tree, not the report: vocabularies carry no close verb (HUMAN_RULING_LABELS=[reject,design,keep-open], PR twin=[ai:reject,human:design]); human_close_steps = comment → close → retire, already-ruled dedup collapses to bare close; cc_gate precedence is writability → human label ruling → torn-close completion → flag lifecycle, shared by vetter state-load and /ncc (one classifier, #179 property held); torn-close detector reads trusted 👤 ruling lines only, keep-open near-collision pinned by test; a later human:* re-ruling DOMINATES a stale torn-close comment (fail-safe: no auto-close against a standing human label); flagged PRs leave the lanes via the CloseCandidate hand-off below the human arms (no double inventory, owner agreement with cc_gate); sweep_stale_closed_flags covers the close→retire tear on both nouns, archived withheld and counted, failures surfaced as rows, search failure non-fatal by design; zero occurrences of the retired label repo-wide including snapshots. Mutation pass: 10/11 killed, the accepted ncc fetch-loop survivor is disclosed in the QA block and is network-loop wiring per repo convention. |
Closes #211
Closes #212
Closes #213
Three rulings (2026-08-05), one machine:
#211 — flags cover both subject types, and the vetter vets both
flagged_subjects_args(noun, state)is the ONE spelling of the label query; the open-side population is nowgh search issuesandgh search prs(the CLI scopes each noun to one subject type, which is exactly how PR-shaped flags were invisible). Either half failing aborts the read — a queue missing half its population is a falsely-empty queue in partial clothes.closeCandidateUnvettedmixes issues and PRs;record_close_candidate_verdictjudges a producer flag on a PR exactly as on an issue, and its reject returns each subject to its own queue (issue → backlog, PR → vet lane). It refuses only the PR whose label is the vetter's owncloseverdict — no producer claim exists there for a second AI judgement.ai:*targets dispose structurally vialabels_to_remove).next_close_candidatereports coverage on a PR row asnot-applicable-subject-is-a-pr(the covering-PRs read is an Issue-type question) and it never blocks.#212 — one upheld inbox, no PR lane state
closeCandidateUpheldis the human's ONE disposal inbox: upheld flags on either subject type plus PRs the vetter verdictedclose(CcGate::VetterClose, actionskip-vetter-close, queued FIFO by the verdict's own timestamp — the moment the subject became the human's).classify_lanehands everyai:close-candidatePR to the flag machinery (Lane::CloseCandidate, excluded fromlanes), below the human-decision arms and above every otherai:*— the same owner precedencecc_gategivesHumanRuled. ThecloseCandidatePrscounts key is gone;queue.presentableonnext_close_candidateis the sum of both human-owned gate states whilecountskeeps them apart (vetterCloseVerdict).#213 — a close is decide+do; the retired ruling-state label is gone everywhere
HUMAN_RULING_LABELS3,HUMAN_PR_RULING_LABELS2, MCP enums match by derivation); the label is out of the sacred/parked sets, the colour map, the lane emit and both counts keys; the org-wide label definitions are being deleted by hand, so no migration code ships.human-closewrites the pinned👤 humancomment, closes, then retires the pending flag — no label at any point. The order is chosen so no tear is invisible, one test per tear point:human_close_ruled+ open) —cc_gateroutes it toCcGate::TornHumanCloseand the vetter state-load executes the recorded close (cc_complete_torn_close; countscompletedHumanClose/humanCloseCompletionFailed, the close-candidate flags can reach two states with no transition that clears them #179 cleared/clear_failures posture);sweep_stale_closed_flags:--state closed --label ai:close-candidate, both nouns, archived repos withheld; countsstaleClosedFlagsCleared/…ClearFailed/…Archived), which also drains the legacy Add slash commands for the human FSM transitions #94 hand-close residue org-wide; the interactivehuman-closere-run (StaleFlag) still works;[Close].next_close_candidatecounts (never presents) the torn state ascounts.tornHumanClose.Verification
cargo fmt --checkclean; clippy adds no new warnings (the onecollapsible_matchwarning pre-exists onmainat an untouched line).grep -r "human:close-candidate"over the repo returns only generatedhuman-queue*snapshot data, which the next cron refresh regenerates; the dashboard counterparts are rain-org-health#158/usage-gate: hold the crons 5% BEHIND pace; retire USAGE_SLACK_PCT (refused, not read) #159 (blocked on this landing).🤖 Generated with Claude Code
QA
a_pr_close_verdict_is_human_owned_not_stranded_and_not_cleared,a_recorded_close_ruling_dominates_the_flag_lifecycle,the_two_close_candidate_inboxes_search_one_population,cc_item_arrays_are_populated_and_agree_with_their_counts,cc_row_classifies_pr_subjects_through_the_same_gate,classify_lane_maps_every_state_by_precedence,lanes_doc_emits_every_state_with_the_right_members,the_close_follows_the_record_and_labels_are_only_ever_removed,every_tear_point_lands_where_machinery_can_finish_it,the_flag_verdict_judges_a_flagged_pr_and_refuses_the_vetters_own_verdict,a_pr_ruling_that_would_strand_a_live_flag_is_refused,the_close_report_names_the_close_as_well_as_the_ruling,the_envelope_states_what_the_page_left_behind,human_ruling_vocabulary_is_derived_from_the_label_sets— each fails on base: the new ones reference symbols base does not have (compile failure; each also proven discriminating by the mutation column below), the extended ones pin values base emits differently (closeCandidatePrs/humanCloseCandidatekeys, 4-entry vocabularies, close-last step order).cc_gateVetterClose arm →NoFlag→a_pr_close_verdict_is_human_owned_not_stranded_and_not_clearedcc_gateTornHumanClose arm disabled →a_recorded_close_ruling_dominates_the_flag_lifecycleFLAG_SEARCH_NOUNS→["issues","issues"]→the_two_close_candidate_inboxes_search_one_populationcc_item_arraysupheld filter dropsskip-vetter-close→cc_item_arrays_are_populated_and_agree_with_their_countsclassify_laneflag arm →Lane::VetterVerdicts→classify_lane_maps_every_state_by_precedencehuman_close_stepsclose moved after removals →the_close_follows_the_record_and_labels_are_only_ever_removedcc_verdict_planrefuses ALL PRs (flag condition dropped) →the_flag_verdict_judges_a_flagged_pr_and_refuses_the_vetters_own_verdictai:*-disposes exception →a_pr_ruling_that_would_strand_a_live_flag_is_refusedqueue.presentabledrops thevetter_closeterm →the_envelope_states_what_the_page_left_behindhuman_close_ruledmatches anyRuledline →every_tear_point_lands_where_machinery_can_finish_itnext_close_candidate_fetch'sTornHumanClose => counts.torn_human_close += 1mutated to incrementpresentable— the increment sits inside the network fetch loop, the same untested-wiring class as every other gate-count increment there; the pure envelope test pins the doc shape, not the loop. Disclosed rather than faked with aghstub the repo does not use.ghCLI'stype:issue/type:prsearch scoping verified live against the org, and the FSM invariants the pre-existing ~1000-test suite already pins.not-applicableon PR rows. Upheld close-candidates are one human inbox: merge closeCandidateUpheld and the vetted-PR lane state #212 asks one upheld inbox and no PR lane state — covered:CcGate::VetterCloseinto the mixedcloseCandidateUpheld,classify_lanehand-off,closeCandidatePrsretired,queue.presentablesumming both human-owned states. human:close-candidate splits decide-from-do, a phase no other state models: fuse close rulings into human-close, machinery completes tears #213 (as refined) asks the label gone everywhere, close as decide+do, torn closes self-healed — covered: vocabularies/sacred/parked/colour-map/lane/counts/MCP schemas purged, comment→close→retire order with a test per tear point,TornHumanClosecompletion plus the closed-side sweep (which also drains the legacy Add slash commands for the human FSM transitions #94 residue); org-wide label-definition deletion is being done by hand per the ruling, so no migration code ships — deliberate, not an omission.Summary by CodeRabbit
New Features
Updates