Skip to content

feat(pr-pipeline): name merge.rung values merge and merge-reviewed - #11914

Merged
kyle-sexton merged 5 commits into
mainfrom
replace-11903-merge-rung-names
Nov 1, 2026
Merged

kyle-sexton merged 5 commits into
mainfrom
replace-11903-merge-rung-names

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Closes #7469

Summary

Replaces #11903, a lanes App pull request whose test-bash (6) shard stayed red after its fix lane ran. This branch merges that head unchanged and adds one fix commit on top.

The original run's summary:

Following the owner's 2026-11-01 recorded decision on #7469, merge.rung now takes off, merge and merge-reviewed, and still accepts C2 and C3 as aliases. The schema, this repo's config, the example, the babysit merge gate's readers and the docs a human reads all use the names, with any code in parentheses. Choice of means: the gate maps a name to its code when it reads the rung (rung_code in babysit_merge_policy.py), at every input: the config, CLAUDE_LANES_MERGE_RUNG_CAP, --lane-rung-cap, --rung and the promotion-cell lookup. Comparisons, refusal reasons (rung-off:*, promotion-unqualified:<rung>) and the --rung values passed between scripts stay unchanged for the JS and Python consumers. The trade-off is that gate reports still show the rung as C2/C3. Any unknown value still reads as off, so an older installed copy of the gate that reads rung: merge holds the lane off and does not merge.

Not covered, carried from #11903:

  • .github/workflows/pr-merge.yml:1463 has a comment saying the rung cap can be set to off (or C2). A person can reword it to name merge.
  • Historical records left as written: CHANGELOG entries and ADR 0082 ("merge.rung stays off, C2 or C3") record past states and were not rewritten.
  • The issue's earlier intake comments proposed renaming the work-class labels. Superseded by the 2026-11-01 decision, so no label was renamed.

Fix

All of #11903's changes (schema enum and descriptions, rung: merge in the config and example, rung_code() in babysit_merge_policy.py, --rung names in babysit_verify_evidence.py, the Python and node schema tests, the docs naming merge (C2) and merge-reviewed (C3), the loop-lane 13.1.1 entry and three changelog fragments), plus:

Verification

Related

Related: replaces #11903

🤖 Generated with Claude Code

melodic-automation-lanes Bot and others added 5 commits November 1, 2026 07:48
Lane-Activity: work-resolve-issue/resolve-issue
…e seam wording

The canonical example now names the rung merge, so the --strict clean-file
assertion in lib/parse-concern-value.test.sh expects merge, not C2.

Revert the seam-to-hook wording edits in the loop-lane README and the
released 4.0.0 changelog entry: they renamed the mechanism in only part of
the section and rewrote a shipped changelog entry, and #7469 needs neither.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review November 1, 2026 13:16
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T13:22:56.352802Z 32b043a Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 32b043aa3e2d3558158679cce86548137aae84c0: read 17 of 17 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #11914 (merge.rung names merge / merge-reviewed)

I found no security issues. I read every hunk of all 17 changed files.

critical-findings: 0

What I checked

Merge-hold modules (trusted paths). These are babysit_merge_policy.py, babysit_verify_evidence.py and the merge settings in docs/conventions/pr-pipeline.yaml. This repository's review rules treat all three as merge-hold controls.

  • rung_code() maps only merge to C2 and merge-reviewed to C3. It passes every other value through unchanged, including None, an empty string and unknown values. As a result:
    • The "unknown value is off" checks against RUNG_RANK still fail closed.
    • None still means "no cap" in effective_rung.
    • An empty --lane-rung-cap still means "no cap".
  • Ranks and cells. Each name gets the same rank and the same promotion cells as its code. Promotion.promoted maps the name to its code before it looks up RUNG_CELLS, so merge-reviewed still needs every C3 cell. No rung gains a rank or skips a cell.
  • Cap inputs. CLAUDE_LANES_MERGE_RUNG_CAP, --lane-rung-cap and --rung all go through the same mapping. A cap still sets the effective rung to the minimum of its inputs, so it can only lower the rung.
  • Config change. docs/conventions/pr-pipeline.yaml moves rung: C2 to rung: merge. That is the same rung with no widening. An older installed copy of the gate reads merge as unknown and therefore off, which is a narrowing.

JS consumers. The resolver passes merge.rung through as written (resolve.mjs:948). enable-auto-merge.mjs sends only the Python room's effective rung back as --rung, and that value is already a code. No JS comparison against C2/C3 sits on a hold path. The config cache check (babysit_merge_policy.py:1303) stores the code that read_config_at has already mapped.

Schema. The enum gains the two names. Both conditional if blocks (local-babysit needs diff-check; pr-merge needs require-verifier-verdict) now list both names and both codes, so neither requirement can be dodged by spelling the rung as a name. The new tests in merge-authority.test.mjs cover this.

Docs, changelogs and tests. These are wording or test changes only. None of them deletes or softens a guardrail instruction.

Other notes

  • Trust controls: no widening of the trusted-actor check, the token scope, the kill switch or the broker. The untrusted-provenance hold is unchanged.
  • PR context: I found no embedded directives aimed at the review lane.
  • Spend: none.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

claude-review reviewed 32b043aa3e2d3558158679cce86548137aae84c0: read 17 of 17 changed file(s); 0 finding(s), 0 as inline comments.

Code review: PR #11914, merge.rung names merge and merge-reviewed

Result: no findings. I read every hunk of all 17 changed files. I also traced the code that reads the rung, outside the changed lines.

How the change works

rung_code() turns a name into its code wherever the gate takes the rung in:

  • the config (read_config_at)
  • effective_rung, for both the config rung and the cap
  • read_rung_cap, which reads CLAUDE_LANES_MERGE_RUNG_CAP
  • rung_cap, which takes --lane-rung-cap
  • Promotion.promoted, which looks up the promotion cells

After that, RUNG_RANK, RUNG_CELLS and the refusal strings still work in codes. I checked the code that consumes those values, outside the diff:

  • pr-merge lane. enable-auto-merge.mjs passes the lane room's effective rung, which is already a code, as --rung. It passes RUNG_CAP as --rung-cap, and rung_cap now reads names there.
  • clear-escalations.mjs. It passes a fixed "C3".
  • Cached config. The check in babysit_merge_policy.py that a cached config is valid (c.rung in RUNG_RANK) only ever sees codes, because read_config_at converts names first.
  • resolve.mjs. It passes merge.rung through unchanged and checks it against the schema, which this PR updates.

I found no other copy of the old ["off","C2","C3"] enum anywhere in the repository. The remaining C2/C3 text in publish-promotion-evidence.mjs, work-resolve-issue/report-outcome.mjs and the babysit-loop docs names work classes or babysit_loop_merge values, not merge.rung.

The line numbers the test cites (example :201 and :207) match the head file docs/conventions/pr-pipeline/examples/claude-code-plugins.yaml.

Closing issue #7469: criteria from the 2026-11-01 decision

  • Schema accepts off, merge, merge-reviewed and still C2/C3; both conditional enums list all four; config and example use the new names. Met. merge-authority.test.mjs checks every spelling against both conditional requirements and checks that C4 is rejected.

  • Every reader resolves the names and the aliases to the same rank and cells, with tests for both spellings. Met. Tests cover config, effective_rung (config rung and cap), read_rung_cap, rung_cap(lane_value=…), Promotion.promoted and the --rung scorer path in verify-evidence.

  • Human-facing docs say the name first, with any code in parentheses. Met for the places that name merge.rung:

    • the pr-pipeline README
    • work-classes.md
    • safety.md
    • the loop-lane README

    As the PR body says, two things are left alone: the comment in .github/workflows/pr-merge.yml (not under docs/ or plugins/), and historical CHANGELOG and ADR text.

Other checks

  • Changelog fragments. source-control minor (new accepted input values), pr-pipeline minor (schema accepts new values), autonomy patch (wording only). Each level fits its change.
  • Plugin manifests. No plugin.json or marketplace.json changed.
  • Path-scoped rules. skill-bodies-state-current-rules.md applies to safety.md, and the edited text states the current rule. No violation.
  • Embedded instructions. I found none in the PR context.

Not verified

The PR body says lib/parse-concern-value.test.sh passes 112/112 and that check-affected passed. That comes from the author; this lane has no shell and ran neither.

Rollout note (no change needed)

The PR body notes that an older installed copy of the gate reads rung: merge as an unknown value, which means off. That holds the lane off rather than merging, so the failure is safe. The repository's own pr-merge lane runs the gate scripts and reads the config from the same default branch.

@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 1, 2026
Merged via the queue into main with commit ae85c38 Nov 1, 2026
74 checks passed
@kyle-sexton
kyle-sexton deleted the replace-11903-merge-rung-names branch November 1, 2026 13:34
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.

Config should name work classes, not C1-C5 codes

1 participant