Skip to content

human-rule delegates in one call, and human:* protects authorship only — rulings are inputs the machine executes - #166

Merged
thedavidmeister merged 13 commits into
mainfrom
2026-07-31-issue-111-rulings-execute
Aug 5, 2026
Merged

human-rule delegates in one call, and human:* protects authorship only — rulings are inputs the machine executes#166
thedavidmeister merged 13 commits into
mainfrom
2026-07-31-issue-111-rulings-execute

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Closes #111

Both halves of the issue land here: the delegation mechanism (the original issue text) and the model it plugs into (the 2026-07-31 update comment carrying the two human rulings). The rulings, verbatim, are the spec for the second half:

"it's dumb to make 'human sacred' because it locks up the fsm permanently, seems like an overreaction to an older version of things where ai was just ignoring human inputs"

"the more we can shift to automation the better, as the human will always be the bottleneck relative to automatable tasks"

Mechanism — the ruling transition carries the work order

human-rule (CLI and MCP, PR and issue) now takes --rework "<order>" / --rework-file <path> / --park:

  • One call, two records, distinct shapes. The ruling comment (👤 human / Ruled <anchor>: …) is provenance — pinned, historical, true forever. The work order (Rework note @<anchor>: <order>) is an instruction, spent once executed. A delegation posts both, ruling FIRST (a PR may carry a ruling with no order — the explicit park — but never an order with no ruling; the step order is a tested property, and a failure between the two is reported loudly as "currently reads as PARKED", never silently).
  • Fail-closed on the marker. REWORK_MARKER is the constant "Rework note", and rework_note_comment is the only writer. A unit test round-trips the emitted comment through the producer's own verification function — trusted_comments(_, Some(REWORK_MARKER)), the exact starts_with read trusted-comments --marker 'Rework note' performs — and asserts a spoofed author is filtered. The hand-typed Rework Note/rework note silent-park failure is unconstructible.
  • Pinned to the same anchor as the ruling (@<head sha> on a PR; the flag/issue anchor on an issue), so ruling and order go stale together and a note written for a superseded tree is distinguishable from one for the current tree.
  • Park is the explicit alternative, never the accidental default. A bare reject or design REFUSES, naming the legal spellings. reject requires --rework and offers no --park at all — a reject IS a send-back; one not worth reworking is a different ruling, and the refusal names them (design --park, close-candidate, human-close). design takes exactly one of --rework/--park. close-candidate/keep-open refuse both flags — the verb is its own disposition, and the close-candidate refusal names human-close as its consumer.
  • The one-command check from the issue holds: one command delegates, one command parks, and intending the first while getting the second is impossible (it is a refusal, not a park).

Model — the human namespace protects AUTHORSHIP ONLY

Per the rulings: no AI actor writes a human:* label; none removes one as an override. Absolute parking was the ruled-out overreaction — a ruling is an INPUT the machine executes, and clearing-by-execution is now modeled:

  • pr_human_sacred narrows: sacred = an absolutely-parking label (human:close-candidate, retired human:reject), a native APPROVED/CHANGES_REQUESTED review, a 👤 human ruling pinned to the CURRENT head, or an un-executed human:design. An EXECUTED delegation (trusted Rework note pinned only to superseded heads — the producer pushed past it) is consumable.
  • The producer's state-load picks a delegated ruling up as a work order: worklist rows classify by design_delegation (Parked/Ordered/Executed) and an Ordered row routes as the new nextAction: rework-ruling, above every CI-derived action. Executed falls through to ordinary fleet duty; Parked stays parked-skip.
  • The vetter's state-load stops fast-skipping human:design from labels alone (only the absolute set is decidable without comments); an executed delegation is un-vetted by the ordinary anchor-staleness path, and record-verdict's plan clears the spent human:design alongside the stale ai:* — the completion of the ruling, through the normal rework → un-vetted → re-vet flow. Authorship protection is intact and tested: the vetter's vocabulary reaches no human:* label, the shared labels_to_remove still never strips human:*, and the un-executed/parked/absolute shapes all still refuse (exit 3).
  • The main.rs ~:285 comment enshrining the old model ("its meaning is ABSOLUTE rather than carved-out … nothing removes one but the human superseding their own ruling") is rewritten to describe the current behaviour, as are the CLAUDE.md invariants, the README state diagram + human-transitions section, and the vet_action ordering rationale.
  • campaign-prompt.txt learns the shape: a human:design PR whose trusted Rework note is pinned to the CURRENT head is a work order (mirroring the reject-with-rework-note language, dispatched via rework-ruling); parked-without-note remains parked-for-human; the producer never touches a human:* label — execute-and-push is its entire part.

Consuming-transition table (every human:* state → its consumer)

State Consuming transition
human:design + order @Head (delegated) PRODUCER: worklistrework-ruling → execute per note → push; the push un-vets, and the vetter's record-verdict clears the spent label (clearing-by-execution)
human:design --park (explicit) HUMAN: superseding ruling (human-rule re-rule / human-close) — the surviving pure park, reachable only by its explicit spelling
human:close-candidate (PR or issue) HUMAN: human-close — a DECIDED close awaiting the human's own terminal edge. This is the smallest honest model, stated rather than left dead silently: closing is the human's act by standing ruling (the cron never closes), so there is no machine execution to model; what changed is that the tool's refusals and docs now NAME human-close as this state's consumer
human:reject (retired, #133) migrate-reject (existing) — sacred and bucketed until migrated
human:keep-open (issue) Not a pending state: a standing constraint consumed continuously — flag-close-candidate refuses over it and the issue stays in the producer's ordinary queue. Nothing waits on anyone, so there is no dead state to exit

Issue-side design/reject rulings take the same --rework/--park spellings (the order posts on the issue, pinned to its anchor). The producer's uncovered-issues state-load already includes human-ruled issues, so an issue-side executable ruling is reachable work; the human-queue backlog VIEW's exclusion of human:* issues is a view, not a gate, and is unchanged.

Deliberately unchanged

  • VET_PROTOCOL stays 4. vetted_at_head is untouched and the vet function (PR-at-head → verdict) is unchanged; what moved is WHEN a verdict may be recorded (the sacred gate) and which spent labels the write sweeps. A protocol-4 verdict is still a value of the current function, so no recompute of the fleet is warranted.
  • classify_lane / HUMAN_DECISION_LABELS still bucket by label (the label is the state); a delegated design PR shows in the human-decisions lane until the re-vet clears it. The dash re-homing of human:design (the HUMAN ACTION → producer action owner flip on rain-org-health) is a separate One reader for the changed-file list, and it says whether the list is whole #148-shaped follow-up, gated on this landing — deliberately not touched here.
  • The five PRs the issue names were the measured cost of the two-call flow; they already carry hand-written notes and need no retrofit.
  • has_human_override keeps its label-presence meaning for the queue's presentability filter and lane domination (a mid-flow PR is not presentable either way).

QA

  • Discriminating tests: the_emitted_work_order_passes_the_producers_own_verification, the_marker_is_the_prompts_exact_spelling, the_ruling_and_the_work_order_stay_two_records_and_the_ruling_leads, an_identical_work_order_dedups_and_a_changed_one_does_not, park_or_delegate_is_an_explicit_choice_never_a_default, the_cli_carries_the_work_order_spellings, design_delegation_reads_the_pin_against_the_head, the_human_namespace_partitions_into_absolute_and_consumable, sacredness_narrows_to_authorship_and_currency, the_re_vet_clears_an_executed_design_as_completion, worklist_routes_an_ordered_ruling_to_the_producer_and_parks_the_rest, no_ai_actor_writes_a_human_label_and_only_execution_clears_one — each fails on base (the delegation symbols do not exist on base, and base's verdict_plan/pr_human_sacred/next_action return RefuseHuman/sacred/parked-skip where these assert the consuming behaviour); MCP surface cases extended in a_human_ruling_validates_or_reaches_no_effect fail on base (bare reject validated there).
  • Mutations applied: see the QA comment — line → mutation → killing test, from a committed baseline.
  • Oracle: the producer's own verification function (trusted_comments + the --marker 'Rework note' prefix read the campaign prompt mandates), the issue text's three requirements (fail-closed marker, same-anchor pin, explicit park) and the update comment's two verbatim rulings; the label-set partition is asserted against PR_SACRED_LABELS itself, not a re-typed list.
  • Category check: issue asks the mechanism (delegation built into human-rule, one call, two distinct records) AND — per the 2026-07-31 update comment — the model (authorship-only protection, live consuming transitions for every human:* state, explicit-only parking, the ~:285 comment rewrite, the campaign-prompt shape); covered all of both. Closes #111.

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Added explicit delegation and parking options for human design decisions.
    • Added rework workflows for rejected pull requests and issues.
    • Delegated work is re-vetted after execution, while parked decisions remain protected.
    • Added clearer handling for QA-block and linkage-related rework.
  • Documentation

    • Updated command usage, workflow guidance, and transition tables.
    • Updated the human-fsm plugin to version 0.10.0.

…rder, and human:* protects authorship only

Mechanism (#111): --rework/--rework-file/--park on human-rule and
human-rule-issue (CLI + MCP). A delegation posts the trusted
'Rework note @<anchor>: ...' work order beside the ruling in ONE call, in
the exact prefix form the producer's trusted-comments marker read accepts
- round-tripped through that same function in a unit test. Ruling and
order stay two records: provenance vs spendable instruction, ruling
always first. A bare reject/design refuses; park is the explicit
minority spelling, never the default.

Model (the 2026-07-31 rulings): the human namespace's protection is
authorship only - no AI actor writes a human:* label, none removes one
as an override - and clearing-by-execution is modeled. pr_human_sacred
narrows: human:design with its work order executed (head pushed past the
pin) is consumable; worklist routes an ordered ruling as rework-ruling;
the re-vet's record-verdict clears the spent label as the ruling's
completion. human:close-candidate and retired human:reject stay
absolute parks (their consumers are human-close and migrate-reject).
VET_PROTOCOL stays 4: the vet function is unchanged, only the record
gate and the label sweep moved.

Closes #111

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3fb40716-e16e-4930-aea3-fcd11df5ad1a

📥 Commits

Reviewing files that changed from the base of the PR and between aef9c94 and 54809bd.

📒 Files selected for processing (8)
  • CLAUDE.md
  • README.md
  • campaign-prompt.txt
  • plugins/human-fsm/README.md
  • plugins/human-fsm/commands/design.md
  • plugins/human-fsm/commands/reject.md
  • pr-review-report-rs/src/main.rs
  • review-prompt.txt

Walkthrough

Changes

Human ruling delegation

Layer / File(s) Summary
Ruling disposition contracts
CLAUDE.md, README.md, plugins/human-fsm/..., pr-review-report-rs/src/main.rs
Human reject and design commands now require explicit delegation or parking. CLI and MCP inputs accept validated rework orders.
Pinned work-order application
pr-review-report-rs/src/main.rs
Ruling application posts the human ruling and a trusted, head-pinned Rework note, with disposition reporting and failure handling.
Delegation state and re-vetting
pr-review-report-rs/src/main.rs, campaign-prompt.txt, review-prompt.txt, CLAUDE.md, README.md
The worklist routes pending rework orders to the producer. Executed design delegations return to vetting and can clear the spent label.
Behavior validation and release updates
pr-review-report-rs/src/main.rs, .claude-plugin/marketplace.json, plugins/human-fsm/.claude-plugin/plugin.json
Tests cover validation, trusted-note parsing, routing, state transitions, and label clearing. Plugin versions change to 0.10.0.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Human
  participant HumanRule
  participant GitHub
  participant Worklist
  participant Producer
  participant Vetting
  Human->>HumanRule: submit ruling with --rework or --park
  HumanRule->>GitHub: record ruling and optional pinned Rework note
  GitHub->>Worklist: expose ruling state
  Worklist->>Producer: route delegated rework
  Producer->>GitHub: push requested changes
  GitHub->>Vetting: provide executed design delegation
  Vetting->>GitHub: record verdict and clear spent label
Loading

Possibly related PRs

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: one-call human-rule delegation and authorship-only human-state protection.
Linked Issues check ✅ Passed The implementation satisfies [#111] by supporting explicit delegation or parking, paired pinned records, trusted markers, issue parity, and fail-closed validation.
Out of Scope Changes check ✅ Passed The code, documentation, prompts, tests, and plugin version updates directly support the delegation and human-state objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-07-31-issue-111-rulings-execute

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

thedavidmeister and others added 2 commits July 31, 2026 11:11
…rts do

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tier-format the prose, and the vetter prompt stops claiming every human:* row is excluded

- the_marker_is_the_prompts_exact_spelling used .expect on
  campaign-prompt.txt, which the flake package's fileset excludes - the
  same graceful let-else bail every other prompt-conformance test uses
- pinned pre-commit (prettier-rainix) over the changed markdown
- review-prompt.txt line 6 said human:*-labelled PRs are ALREADY
  EXCLUDED from unvetted; after #111 an EXECUTED human:design delegation
  is listed, and the prompt now says what that row means

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

QA evidence — test + adversarial-mutation pass for the #111 delegation change.

Suite: full cargo test green at the head (648 unit + 69 integration tests; the 12 new delegation_111_tests plus extended mcp_tests/worklist_tests cases). cargo clippy --all-targets -- -D warnings clean; cargo fmt clean.

Round-trip (the issue's own check): the_emitted_work_order_passes_the_producers_own_verification feeds the tool-emitted comment back through trusted_comments(_, Some(REWORK_MARKER)) — the same starts_with marker read trusted-comments --marker 'Rework note' performs — and asserts it returns, that the anchor parses back to the ruling's sha, and that the identical text from an untrusted author is filtered.

Mutation pass (from the committed baseline, one mutant at a time, whole suite per mutant, source restored between — all 9 KILLED):

Mutation (line → change) Killed by
rework_note_comment: emit Rework Note (the exact hand-typed bug the issue names) the_emitted_work_order_passes_the_producers_own_verification + 5 more
design_delegation: no-note PR reads Executed (a parked design becomes clearable) design_delegation_reads_the_pin_against_the_head, sacredness_narrows_to_authorship_and_currency, the_re_vet_clears_an_executed_design_as_completion, worklist_routes_…
pr_human_sacred: design clause inverted (!=== Executed) sacredness_narrows_to_authorship_and_currency, the_re_vet_clears_…, one_reject_state_tests::a_ruling_never_parks_a_pr_with_no_head_to_pin_to
verdict_plan: executed human:design not pushed onto to_remove (label leaks past the re-vet) the_re_vet_clears_an_executed_design_as_completion
next_action: work-order branch deleted (ordered ruling routes by CI) worklist_routes_an_ordered_ruling_to_the_producer_and_parks_the_rest, worklist_tests::human_override_parks_over_stale_ai_label_ci_and_deploy
with_rework_note: order inserted before the ruling comment the_ruling_and_the_work_order_stay_two_records_and_the_ruling_leads
human_rule_args (MCP guard): invalid choice silently becomes PARK (the accidental default back) mcp_tests::a_human_ruling_validates_or_reaches_no_effect
PR_PARKED_HUMAN_LABELS: human:design moved into the absolute set (#157-style adjacent-gate partition) the_human_namespace_partitions_into_absolute_and_consumable + 3 more
worklist_row: explicit-park clause dropped (a --park design becomes CI-routed) worklist_routes_an_ordered_ruling_to_the_producer_and_parks_the_rest

ruling_work's matrix needs no separate mutants: park_or_delegate_is_an_explicit_choice_never_a_default asserts every arm of the truth table directly (legal → the exact RulingWork, illegal → refusal naming the legal spelling), so any arm flip fails it by construction.

Authorship protection re-verified after the narrowing: no_ai_actor_writes_a_human_label_and_only_execution_clears_one (vetter vocabulary reaches no human:*; the shared labels_to_remove never strips human:*), plus the un-executed/parked/absolute refusal arms in the_re_vet_clears_an_executed_design_as_completion and the still-passing pre-existing sacred-gate suite (verdict_plan_refuses_a_human_overridden_pr, forged-marker, TOCTOU tests).

thedavidmeister and others added 2 commits July 31, 2026 11:24
review-prompt step 1 and CLAUDE.md's unvetted row take the UNION of #111
(delegation: executed human:design rows appear un-vetted) and #161
(ai:blocked-on clearance inside the same state-load).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
153 commits of `main` merged in (merge base e9029ed), 88 of them touching
pr-review-report-rs/src/main.rs. `main` won everywhere it moved alone; every
region both sides changed is resolved as the UNION of the two intents, never a
winner. Nothing about what #111 does was changed.

pr-review-report-rs/src/main.rs (2 hunks)

- worklist_row's JSON row. #111 replaces the `has_human_override` local with the
  delegation-aware pair, and main added `reviewDecision` to the same object.
  Union: `humanOverride` keeps its LABEL-PRESENCE meaning (computed straight
  from `has_human_override(detail)`), `humanWorkOrder` rides beside it, and
  main's `reviewDecision` field is kept verbatim with its comment — 2z reads the
  approved set off the row and re-deriving it with `gh search prs` is the cost
  that field exists to remove.
- End of file: append/append. #111 adds `mod delegation_111_tests`, main adds
  `mod work_tokens_tests` (the `work-tokens` subcommand). Both modules kept.

pr-review-report-rs/src/main.rs — minimal_args, a real semantic interaction

`minimal_args` is NEW on main; its `human_rule` / `human_rule_issue` arms passed
`ruling: "reject"` with no work order. Under #111 that is no longer a minimal
call, it is an INVALID one: `ruling_work` refuses a bare reject because a reject
IS a send-back. `each_refusal_names_an_argument_that_actually_narrows_it` then
failed on its own guard ("refused for some OTHER reason, so this test proved
nothing") — the guard working exactly as designed. Fixed at the root: both arms
now carry `rework`, which is what the minimum for those two tools now is. The
test is unweakened and the doc comment's claim that the arms state what a
minimal call looks like stays true.

campaign-prompt.txt

- step 2(a): main added `reviewDecision` to the row's field list; #111 added
  `rework-ruling` to the `nextAction` list. Both, with `rework-ruling` ahead of
  `parked-skip`, matching `next_action`'s arm order.
- step 3: main rewrote 3b for the run budget, #111 added the DESIGN RULINGS
  DELEGATE THE SAME WAY (#111) paragraph to step 3. Both.

review-prompt.txt

Step 1 was rewritten by both. Kept main's RUN BUDGET paragraph whole and swapped
in #111's replacement for the exclusion sentence — "PRs a human still HOLDS
(an absolutely-parking `human:*` label, …, or a `human:design` whose work order
is not yet executed)" plus the EXECUTED-delegation sentence — because that
sentence is the one #111 changes and the budget is the one main changes. Main's
rewritten `counts` bullet is kept as-is; #111 never touched it.

CLAUDE.md

Main's transitions table is a superset (state-load, await, preflight,
sol-toolchain, open_pr, push, work-tokens, already-fixed …). Kept it whole and
replaced exactly one row — `human-rule`, the only row #111 rewrites.

plugins/human-fsm/README.md

Kept main's table including its new `/ncc` row; took #111's `/reject` and
`/design` rows (the `--rework`/`--park` spellings).

.claude-plugin/marketplace.json + plugins/human-fsm/.claude-plugin/plugin.json

Version bumps on both sides: 0.6.0 → 0.7.0 (this branch) vs 0.6.0 → 0.9.2
(main). Resolved to 0.10.0 in BOTH files — this branch's bump was a minor one
for a new capability, so the same intent applied over main's 0.9.2 is 0.10.0.
Main's descriptions (which name /ncc) are kept. `plugin-version-lockstep`
passes: `ok human-fsm 0.10.0`.

Verified after the merge

- pr_human_sacred stays FIRST in verdict_plan, ahead of the no-sha refusal, with
  the spent-`human:design` clearing after it.
- next_action's order is human_parked → ReworkRuling → modeled-ai:* park →
  deploy → CI classifier. Main inserted no arm above the two human ones.
- unvetted_fetch's cheap pre-filter reads `pr_absolutely_parked`; the `--queue`
  presentability filter still reads `has_human_override` (label presence), which
  is what that view wants and what the branch left it as.
- Every PrSignals field main carries is populated in worklist_row.
- VET_PROTOCOL stays 4 — main did not bump it and neither does this.
- labels_to_remove still strips only `ai:*`; no vetter-reachable vocabulary
  names a `human:*` label.
- #209's `every_org_wide_enumeration_withholds_archived_repos` passes unchanged:
  #111 adds no org-wide enumeration, so the filtered/exempt sets need no edit.
- #207's `cc_gate` keeps `RepoArchived` as its first arm ahead of the sacred arm;
  #111 touches PR sacredness only, not the issue-side classifier.

cargo build clean; cargo test 1053 passed / 0 failed (975 bin + 78 across the
six integration targets); rainix-rs-static (cargo fmt --check + cargo clippy
--all-targets --all-features -D warnings -D clippy::all, after touching main.rs)
exit 0 with no warnings; pre-commit run --all-files all hooks Passed (denofmt
re-aligned the two markdown tables).

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

Copy link
Copy Markdown
Contributor Author

Base merge: main (8abf070) merged in — conflicts resolved as unions

Merged origin/main into this branch (aef9c94, parents f9b0613 + 8abf070). No rebase, no force-push, no branch deletion. Merge base was e9029ed, 153 commits behind main, 88 of them in pr-review-report-rs/src/main.rs.

main won everywhere it moved alone. Every region both sides touched is the union of the two intents — nothing about what this PR does changed.

What conflicted, and how

pr-review-report-rs/src/main.rs — 2 hunks

  1. worklist_row's JSON row. This PR replaces the has_human_override local with the delegation-aware pair; main added reviewDecision to the same object. Resolved as all three: humanOverride keeps its label-presence meaning (computed straight from has_human_override(detail), unchanged semantics for the dashboard), humanWorkOrder rides beside it, and main's reviewDecision field is kept verbatim with its comment — step 2z reads the approved set off the row, and re-deriving it with gh search prs --review approved is exactly the cost that field was added to remove.
  2. End of file — append/append. This PR appends mod delegation_111_tests; main appends mod work_tokens_tests (the work-tokens subcommand). Both modules kept.

campaign-prompt.txt — 2 hunks. Step 2(a): main added reviewDecision to the row's field list, this PR added rework-ruling to the nextAction list — both, with rework-ruling placed ahead of parked-skip so the prose matches next_action's arm order. Step 3: main rewrote 3b for the run budget, this PR added the "DESIGN RULINGS DELEGATE THE SAME WAY (#111)" paragraph to step 3 — both.

review-prompt.txt. Step 1 was rewritten by both sides. Kept main's RUN BUDGET: 3 ITEMS PER RUN paragraph whole and swapped in this PR's replacement for the exclusion sentence — "PRs a human still HOLDS (an absolutely-parking human:* label, …, or a human:design whose work order is not yet executed)" plus the EXECUTED-delegation sentence. Those are two different sentences changed for two different reasons, so the union is exact. Main's rewritten counts bullet is kept as-is; this PR never touched it.

CLAUDE.md. Main's transitions table is a superset (state-load, await, preflight, sol-toolchain, open_pr, push, work-tokens, already-fixed, …). Kept it whole and replaced exactly one row: human-rule, the only row this PR rewrites.

plugins/human-fsm/README.md. Kept main's table including its new /ncc row; took this PR's /reject and /design rows (the --rework / --park spellings).

.claude-plugin/marketplace.json + plugins/human-fsm/.claude-plugin/plugin.json. Version bumps on both sides: 0.6.0 → 0.7.0 (this branch) vs 0.6.0 → 0.9.2 (main). Resolved to 0.10.0 in both files — this branch's bump was a minor one for a new capability, so the same intent applied over main's 0.9.2 is 0.10.0. Main's descriptions (which name /ncc) are kept. plugin-version-lockstepok human-fsm 0.10.0.

One real semantic interaction with merged work

minimal_args is new on main, and its human_rule / human_rule_issue arms passed ruling: "reject" with no work order. Under #111 that is no longer a minimal call, it is an invalid one — ruling_work refuses a bare reject because a reject IS a send-back. each_refusal_names_an_argument_that_actually_narrows_it then failed on its own guard:

human_rule was refused for some OTHER reason, so this test proved nothing:
reject requires --rework "<work order>" (or --rework-file <path>) …

That guard doing its job is the whole point of it, so this is fixed at the root rather than around it: both arms now carry rework, which is what the minimum for those two tools now is. The test itself is unweakened, and its doc comment's claim that the arms "double as a statement of what a minimal call to each transition looks like" stays true. No test was deleted or relaxed.

Interaction with #209 and #207 — nothing for a reviewer to chase

Semantic checks against the merged tree

  • pr_human_sacred is still called FIRST in verdict_plan, ahead of the no-sha refusal, with the spent-human:design clearing after it.
  • next_action order is human_parkedReworkRuling → modeled-ai:* park → deploy → CI classifier. Main inserted no arm above the two human ones.
  • unvetted_fetch's cheap pre-filter reads pr_absolutely_parked (both call sites). The --queue presentability filter still reads has_human_override — label presence is what that view wants, and this PR deliberately left it.
  • Every PrSignals field main carries is populated in worklist_row.
  • VET_PROTOCOL stays 4. Main did not bump it and this merge does not either.
  • labels_to_remove still strips only ai:*; no vetter-reachable vocabulary names a human:* label.

Numbers

Gate Result
cargo build clean
cargo test 1053 passed, 0 failed, 0 ignored — 975 (bin) + 3 + 9 + 47 + 8 + 7 + 4
rainix-rs-static (cargo fmt --all --check + cargo clippy --all-targets --all-features -- -D warnings -D clippy::all) exit 0, 0 warnings — run after touch pr-review-report-rs/src/main.rs so a warm target could not mask a lint
pre-commit run --all-files exit 0, all 11 hooks Passed (denofmt re-aligned the two markdown tables on its first pass)
plugin-version-lockstep ok human-fsm 0.10.0

Nothing was left unresolvable as a union.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 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 `@campaign-prompt.txt`:
- Line 45: Update the producer instructions in campaign-prompt.txt to remove
executable raw gh operations, including gh search prs, gh pr view, gh pr checks,
gh run view, and gh pr checkout. Replace each with the corresponding sanctioned
pr-review-report workflow or subcommand for discovery, inspection, checks, run
status, and checkout/state transitions. Preserve raw gh command names only where
the text explicitly forbids their execution, and ensure all GitHub input/output
uses typed pr-review-report operations.

In `@plugins/human-fsm/commands/design.md`:
- Around line 24-34: Update the changed fenced command blocks in the design
documentation, including the blocks around the rework, park, and line 52
commands, by adding an appropriate language tag such as text to each opening
fence so markdownlint MD040 passes.
- Around line 49-54: Preserve the selected issue-side disposition across the
human-fsm documentation. In plugins/human-fsm/commands/design.md lines 49-54,
update the human-rule-issue fallback to pass the same --park or --rework <WORK
ORDER> choice instead of always using --rework. In plugins/human-fsm/README.md
lines 17-18, document the required disposition arguments for both reject and
design flows.

In `@pr-review-report-rs/src/main.rs`:
- Around line 15401-15432: Extract the duplicated work-order disposition logic
into a shared ruling_work_parts helper taking the subject &Value, anchor, and
&RulingWork, returning (Option<String>, bool, &'static str), then use it at both
parallel call sites with prj and j respectively. Extract the dry-run formatting
match into dry_run_work_line(body, deduped), and replace both inline blocks with
these helpers while preserving the existing wording and behavior.
- Around line 53999-54035: Add a malformed pinned-note case to
design_delegation_reads_the_pin_against_the_head using an empty anchor, such as
“Rework note @: do X” or whitespace-only anchor text. Assert it returns
Delegation::Parked for both the current and changed heads, preserving the
fail-safe behavior of rework_note_anchor when it returns None.

In `@README.md`:
- Around line 177-181: Update the README passage describing sanctioned human:*
label removals to clarify that the two listed paths are normal runtime paths,
while explicitly acknowledging the one-time migrate-reject transition that
removes retired human:reject. Preserve the existing explanations for author
removal and clearing-by-execution.
- Around line 113-116: Update the public command syntax documentation so
disposition flags are advertised only for the reject and design rulings: in
README.md lines 113-116, split or annotate both human-rule tables accordingly,
and in CLAUDE.md line 119 narrow human-rule syntax to reject/design. Keep
close-candidate and keep-open documented without --rework or --park.
🪄 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: ba7fa610-91d1-4b8c-b9dc-66e149fc737a

📥 Commits

Reviewing files that changed from the base of the PR and between 8abf070 and aef9c94.

📒 Files selected for processing (10)
  • .claude-plugin/marketplace.json
  • CLAUDE.md
  • README.md
  • campaign-prompt.txt
  • plugins/human-fsm/.claude-plugin/plugin.json
  • plugins/human-fsm/README.md
  • plugins/human-fsm/commands/design.md
  • plugins/human-fsm/commands/reject.md
  • pr-review-report-rs/src/main.rs
  • review-prompt.txt

Comment thread campaign-prompt.txt
Comment thread plugins/human-fsm/commands/design.md Outdated
Comment thread plugins/human-fsm/commands/design.md
Comment thread pr-review-report-rs/src/main.rs Outdated
Comment thread pr-review-report-rs/src/main.rs
Comment thread README.md Outdated
Comment thread README.md Outdated
thedavidmeister and others added 2 commits August 5, 2026 11:39
…as given

/design offers --rework and --park, and the fallback for the
`is an ISSUE, not a pull request` refusal named only --rework — so a
reader who chose --park, hit the refusal and copied what was in front of
them delegated what they meant to park.

The fallback now shows both spellings and says to carry the one already
chosen, with the mechanical difference under it: --rework posts the
trusted work order beside the ruling, --park posts no order at all.

The plugin README's /reject and /design rows spell the issue-side call
with its flags for the same reason, each with the rule that binds it —
--rework required on either subject for reject, exactly one of the two
for design.

reject.md is deliberately unchanged: `ruling_work`'s "reject" arm errors
on (None, _) and has no (None, true) arm, so --park is unspellable there
and its fallback has exactly one disposition to carry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both public tables advertised `[--rework …|--park]` as part of every
ruling's syntax. `ruling_work`'s `_` arm refuses both on close-candidate
and keep-open — the verb is its own disposition — so the tables named
flags the code rejects, and the two disagreed with each other besides
(README's human-rule-issue row carried them, CLAUDE.md's did not).

Both syntax columns now stop at "<note>", and the rule is stated where it
holds: reject REQUIRES --rework (or --rework-file), design takes exactly
one of --rework / --park, and close-candidate / keep-open take neither.
The prose under the README table gained the same missing half — it stated
reject's requirement and design's exclusive choice and said nothing about
the two verbs that refuse both.

The same section claimed exactly TWO sanctioned removals of a `human:*`
label while `migrate-reject` is a third. They are not the same kind of
move, so the count is split rather than bumped: two RUNTIME removals
(the author superseding their own ruling, and clearing-by-execution),
plus a MIGRATION over the fixed population still carrying the
`human:reject` #133 retired.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
thedavidmeister and others added 6 commits August 5, 2026 11:40
`command_contract` reads every line inside a command's fenced blocks as
something the caller runs, and the opening fence's info string was one of
them — so ```text refused as "not a transition of this binary", which is
a markdown lint answered with a contract violation.

The info string is dropped with the fence it belongs to. Nothing else
about the rule moves: every remaining line must still be a
`pr-review-report` transition or a slash command, and a raw gh/git state
change is still refused wherever it sits.

`a_fence_language_tag_is_markdown_and_buys_a_command_nothing` pins both
halves, because "skip the info string" is one careless edit from "skip
the first command": four fence spellings of the same block agree, a raw
`gh pr edit` smuggled in below a legal transition is still refused, and a
block whose only line is the tag still runs nothing.

With that, design.md's and reject.md's command blocks carry `text` tags
(MD040) — this branch rewrites the command inside every one of them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`rework_note_anchor` returns None when the parsed anchor is empty, and
no case drove that branch: `design_delegation` was tested with a
well-formed pin and with a legacy unpinned note, so deleting the guard
left the whole suite green.

The guard is load-bearing. An empty pin names a head no push can ever
match, so a note reading as pinned-but-empty would classify as
Delegation::Executed on the FIRST push past it — `pr_human_sacred` stops
treating the PR as parked and `verdict_plan` clears a `human:design` no
producer was ever ordered to work.

`design_delegation_reads_the_pin_against_the_head` now covers both the
parser and the classifier, at a matching AND a moved head. The
whitespace spelling is there on purpose: "Rework note @   : do X" parses
to "   ", non-empty until trim() runs, which is a different intermediate
from the bare "@:".

Mutation: with the `if anchor.is_empty()` guard deleted, the parser
assertion fails on Some("") and the classifier assertion fails with
Executed where Parked is required.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
human_rule_pr_apply and human_rule_issue_apply built rework_body,
computed note_deduped, took the report tail and formatted the dry-run
line in byte-for-byte parallel, differing only in which subject had been
fetched (prj vs j). Two sites means a change to the disposition wording
or the dedup rule has to land twice, and one missed site is two different
human-facing reports for the same disposition.

`ruling_work_parts(subject, anchor, work)` returns the three values, and
`dry_run_work_line(body, note_deduped)` formats the dry-run tail; both
sit beside `ruling_work_report`, where the disposition's other pure piece
already lives. Each call site collapses to one line, and the fetch
difference — the one thing that actually differs — is what is left
visible.

rework_body stays owned, since the write path consumes it with
.filter(|_| !note_deduped); the dry-run path borrows it with as_deref().
No clone added, no behaviour changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ork-ruling kept in the enumeration, design-delegation paragraph reinserted, work-order priority above the parked classifier, 0.10.0
bdc9d1a reshaped main.rs when it composed #111's delegation against
main after the ai:blocked-deploy retirement landed. The five review
fixes sit on the pre-merge tree; this brings them onto the current head.
`denofmt` recomputes a markdown table's column widths from its widest
cell, so shortening the `human-rule` / `human-rule-issue` syntax columns
(9d4c1ce) and spelling the issue-side flags into the plugin README's
`/reject` and `/design` rows (7b85ad6) moved every pipe in three tables.
The prose paragraph under the README table rewraps for the same reason —
its first line absorbed the sentence 9d4c1ce ended.

`bdc9d1af` was `deno fmt --check` clean, so this is entirely churn from
this branch's own edits, not a pre-existing red. Content unchanged: the
diff is padding, pipe alignment and wrap points only.

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

Copy link
Copy Markdown
Contributor Author

CodeRabbit review addressed — 6 fixed, 1 rejected

Head is now 54809bd08f787a77504fdd5f5da412befcb8e710, a merge of five review-fix commits with bdc9d1af (the #162 retirement compose), plus one formatting commit the fixes made necessary.

Thread Verdict Commit
campaign-prompt.txt:45 — raw gh in the producer prompt rejected
design.md:34 — MD040 language tags fixed 18b5cb4
design.md:54 — issue-side fallback loses the disposition fixed 7b85ad6
main.rs:15480 — duplicated work-order disposition block fixed b039a79
main.rs:54482 — untested empty-anchor guard fixed fcceb28
README.md:117 — disposition flags advertised on every ruling fixed 9d4c1ce
README.md:182migrate-reject contradicts "exactly two" fixed 9d4c1ce

The one rejection: the edit to campaign-prompt.txt line 45 adds the #111 design-delegation clause, which routes through pr-review-report trusted-comments. The gh mention set on that line is identical before and after (2× gh search prs, 1× gh pr edit, the last already in its prohibition), and none of the five commands the finding names appear on it — they live on lines 8, 30, 35, 46, 47, 48, 54, 58, 59, none touched here. Pre-existing text, not this change.

Two of the six needed more than the reported symptom:

  • 18b5cb4 is not just three fence tags. command_contract was reading a fence's opening info string as a line the caller runs, so ```text was refused as "not a transition of this binary" — a markdown lint answered with a contract violation. The info string is now dropped with its fence, and a_fence_language_tag_is_markdown_and_buys_a_command_nothing pins that it did not become "skip the first command": four fence spellings agree, a raw gh pr edit under a legal transition is still refused, a block whose only line is the tag still runs nothing.
  • 9d4c1ce also fixed a disagreement between README and CLAUDE.md that the finding did not mention (README's human-rule-issue row carried the flags, CLAUDE.md's did not), and the same hole in the prose under the README table.

QA on the composed tree

Everything below was run against 54809bd, not against the pre-merge branch.

Gate Result
cargo build --all-targets clean, 0 warnings
cargo test 1062 passed / 0 failed across 7 targets
rainix-rs-static (cargo fmt --all --check + cargo clippy --all-targets --all-features -- -D warnings -D clippy::all) clean, pinned rainix 53e96a7d, clippy 0.1.94
pre-commit run --all-files all 11 hooks pass

b039a79 was checked for behaviour identity rather than assumed: ruling_work_parts is a verbatim lift of both blocks, and dry_run_work_line's only signature change is &Option<String>Option<&str>, where .replace('\n', " / ") yields the same string either way.

Mutation, re-run on the composed tree

Deleting if anchor.is_empty() { return None } from rework_note_anchor fails exactly design_delegation_reads_the_pin_against_the_head and nothing else — left: Some(""), right: None, 1061 passed / 1 failed. Guard restored, suite back to 1062 / 0, working tree clean.

One commit beyond the merge

54809bd is a denofmt reflow. deno fmt recomputes a markdown table's column widths from its widest cell, so shortening the human-rule syntax columns (9d4c1ce) and spelling the issue-side flags into the plugin README's rows (7b85ad6) moved every pipe in three tables. bdc9d1af was verified deno fmt --check clean beforehand, so this is churn from this branch's own edits rather than a pre-existing red. Content unchanged — padding, pipe alignment and wrap points only.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reviewed 54809bd: ready

Verified before merge: 20 SUCCESS / 1 skipped, MERGEABLE/CLEAN, 0 unresolved threads, 1062 tests, rainix's PINNED clippy (0.1.94 via 53e96a7d) and 11/11 pre-commit hooks clean. Re-verified mergeable AFTER #204 landed on main. I located each fix in the merged tree rather than relaying the report.

Both halves of #111 land here. The MECHANISM: human-rule (CLI and MCP, PR and issue) takes --rework/--rework-file/--park, so one call rules and delegates; REWORK_MARKER is a constant and rework_note_comment its only writer, so the hand-typed Rework Note that silently parks a PR is unconstructible — proven by round-tripping the emitted comment through the producer's OWN verification function, the exact starts_with that --marker 'Rework note' performs. Park is never the default: bare reject and bare design REFUSE, and each refusal names the legal spellings.

The MODEL, from the two rulings on the issue: human:* protects AUTHORSHIP only, not permanence. PR_SACRED_LABELS splits into an absolutely-parking subset, human:design is sacred only while design_delegation != Executed, and the clearing is gated INSIDE verdict_plan behind its own pr_human_sacred call, ahead of the no-sha refusal — so it is unreachable for a parked or still-ordered ruling BY CONSTRUCTION, not by caller discipline. That is the property I checked hardest, because a caller-obligation version of the same design would be one forgotten call site away from clearing a live human ruling.

All five review fixes confirmed present in the tree: ruling_work_parts at 15299 called from BOTH 15482 and 15612 (and dry_run_work_line likewise, so the duplicated disposition block is gone); the anchor.is_empty() guard at 14763; design.md's issue-side fallback now printing BOTH spellings under "the same disposition you chose above", so a --park reader can no longer copy out a delegation; README's "exactly two sanctioned removals" now "two RUNTIME" plus a NAMED third, migrate-reject as a one-shot migration over a fixed shrinking population — better than making it "three", because it says why it is not one of the two paths a live ruling can take; and CLAUDE.md's generic syntax no longer advertising flags ruling_work refuses.

The empty-anchor test is the one worth singling out, because it records the CONSEQUENCE rather than the mechanics: a note that read as pinned-but-empty would name a head no push can ever match, so the FIRST push past it would classify the delegation as executed and let the re-vet clear a human:design no producer was ever ordered to work. Its surrounding cases cover spoofed authorship, mixed pinned/unpinned notes and an empty head — each landing on Parked, the fail-safe. Mutation re-run on the COMPOSED tree: deleting the guard fails exactly that test, left: Some(""), right: None.

Two caveats recorded rather than hidden, neither blocking. Executed means "a trusted note pinned only to superseded heads", i.e. the head MOVED — so a push that is not an execution reads as one. That is the 2026-07-04 sequence vet_action's own doc cites, deliberately re-admitted per the ruling, mitigated by rework-ruling outranking every CI-derived action and by the vetter re-judging with the ruling in humanComments; it is a model-judgement backstop, not a typed one. And TRUSTED_AUTHOR is the same account the producer runs as, so "trusted" means not-third-party-spoofed rather than written-by-the-human — pre-existing across the whole trust model, not introduced here.

One fix beyond the merge, worth knowing it was not cosmetic: a denofmt reflow of three markdown tables. deno fmt recomputes column widths from the widest cell, so shortening the syntax columns and spelling the flags into the plugin README moved every pipe. bdc9d1af was verified deno fmt --check clean first, so this is churn from the branch's own edits and it would have redded CI either way.

@thedavidmeister
thedavidmeister merged commit 21d66cb into main Aug 5, 2026
21 checks passed
thedavidmeister added a commit that referenced this pull request Aug 7, 2026
…ject

Review of the live population found the note-as-order fallback cannot fire
on it. All six open human:design PRs (rain.erc4626.words#233 #166,
raindex#2778 #2721 #2720, cyclo.site#412) predate the marker-emitting
ruling transition: each carries the label alone, with no trusted 👤 human
comment and no Rework note, so no order is recoverable for any of them.

Mapping those to ai:reject would assert an answer nobody gave AND land
them in the producer's queue as orderless rejects — a state
campaign-prompt.txt defines as inert ('a reject-labelled PR WITHOUT any
trusted note is PARKED for a human'), so six unanswered design questions
would go neither answered nor asked.

So migrate_design_pr_plan maps by whether the ANSWER is recoverable:

- Answered (a trusted order live at head, or a trusted ruling whose note
  can be posted as one) -> ai:reject + that order, as before.
- Unanswered (neither) -> ai:design, the machine's own state for 'a human
  must answer this', which is the /nd queue.

MigrateOrder loses its Unrecoverable arm: it now describes only where a
recoverable order comes from, and recoverability decides the TARGET.

Also:
- strands_flag_error states the reason that always holds. A comment-only
  design ruling writes no label and strands nothing, so the message leads
  with the anchor rationale (it would pin to close-candidate @<at>, the
  record of judging the flag, while answering something else) and keeps
  the stranding note for rulings that do write a label.
- last_human_ruling_note only carries a SEND-BACK verb's note forward.
  A torn human-close leaves a trusted close ruling on an OPEN subject,
  and its note is a close reason, not an order to hand a producer.
- CLAUDE.md states that issue-side design writes no label.

Refs #219

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

human-rule can park a PR but cannot delegate it — the rework note has no tool

2 participants