Skip to content

Match a PASS writer against the roster case-insensitively in pass-label - #2547

Open
HugoXK wants to merge 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-pass-label-writer-case
Open

HugoXK wants to merge 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-pass-label-writer-case

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #2544

Owner: Dev-4
Reviewer: Birfy
Written-by: Dev-4
Claim-Id: a91e62dd206541bbab9c6e2898d04642
Risk tier: T2
Base: d400edb

What changed

pass-label compared a PASS writer with writers.includes(report.writer) — an exact string
compare — while the gates compare the same name case-insensitively: review-gate.mjs builds its
writers set from lowercased roster entries and compares name.toLowerCase(), and merge-gate
imports that same decide. So Written-by: reviewer (or dev4) against a roster entry Reviewer
was a valid conclusion for the gates and null for the label job: no pass label, no note. The
stranger path did not rescue it either — strangerPassOf lowercased both sides, so it counted that
same writer as listed and stayed silent. #739's visible trace was dropped exactly where the gate
already accepted the PASS.

After: one helper, isListedWriter(writers, name), compares case-insensitively, and both
verdictOf and strangerPassOf call it, so the two readers cannot drift again. Nothing widens: a
name that is in the roster in no letter case still yields null (negative controls in the test:
reviewer3, Reviewer Extra).

Files: .github/scripts/pass-label.mjs +8/−3, .github/scripts/pass-label.test.mjs +16/−0,
changelog.d/2544-pass-label-writer-case.fixed.md +1/−0 — 3 files, +25/−3.

Verification at the tip

Every reading below was taken on the tree c0581a84ec60c1e7c35a64ad0997621d9da452cc (local commit 2d482910a5dda4f803e5991de4c70e38a161741e), after the single generate run and against main at d400edb74798b71e233eccd46f221eaef782ff5d, which has not moved since the branch was cut. The push helper re-created that local commit as the tip bc0e72eb07df045bdbe1232a5c870e8eca41f765 from the same tree, so the tree these checks measured is the tree at the tip.

Ran:

  • Red first on clean d400edb74798b71e233eccd46f221eaef782ff5d with only the new test present:
    node --test .github/scripts/pass-label.test.mjs → # tests 12 / # pass 11 / # fail 1:
    not ok 3 - #739: a writer matches the way the gates match it, whatever its case
      error: 'reviewer is a listed name in another case'
      expected: true
      actual: ~
    
  • At the tip, same file: # tests 12 / # pass 12 / # fail 0.
  • Adjacent gate suites (review-gate, merge-gate, enqueue-guard, review-verdict):
    # tests 286 / # pass 286 / # fail 0.
  • Whole .github/scripts/*.test.mjs: # tests 669 / # pass 669 / # fail 0, exit 0.
  • node scripts/ds-bot-patches.mjs generate, run once: it rewrote the patch files and
    git status --short -uno stayed empty, so no generated artifact changed. node scripts/ds-bot-patches.mjs check: ok ds-bot/ = Fei2411/DeepSeek-Bot@2b10c70 (tree 5834c00, v0.1.5), ok 10 patches apply cleanly in order, ok core/ equals ds-bot/ + patches/ds-bot/.
  • node scripts/ds-bot-patches.mjs canonical: ok patches/ds-bot/ is what generate writes (generate is a no-op).
  • ARCH_DOCS_BASE=d400edb74798b71e233eccd46f221eaef782ff5d node core/scripts/check-arch-docs.mjs
    → arch-docs: OK (3 changed file(s)).
  • node core/scripts/build-client.mjs --check → exit 0.
  • node .github/scripts/changelog.mjs check → changelog: 39 fragment(s) in changelog.d/ are well formed.

Not run (and why):

  • npm run verify end to end: it cannot run on this machine. Its first step is core lint, which
    needs oxlint; core/node_modules/.bin/oxlint does not exist and npx cannot fetch it, so the
    command stops on a missing tool rather than on this change. The verify steps this change can
    touch were run one by one above; the core suite, the plugin lint and the plugin suites were not
    run.
  • The .github/scripts suite was run with npm_config_cache pointed inside the worktree, because
    the home npm cache is read-only here.

Checkpoint

{
  "pr": 2547,
  "claim": "Dev-4",
  "issue": 2544,
  "summary": "The pass-label job compared a PASS writer with the review policy roster by exact string, while review-gate and merge-gate compare the same name case-insensitively, so a PASS the gates accepted could leave no label and no note. One helper, isListedWriter, now makes both readers of a conclusion compare the same way, so they cannot drift again. A name the roster does not hold in any letter case still counts for nothing. A changelog fragment records the visible fix.",
  "files": [
    ".github/scripts/pass-label.mjs",
    ".github/scripts/pass-label.test.mjs",
    "changelog.d/2544-pass-label-writer-case.fixed.md"
  ],
  "checks": {
    "ran": "node --test \".github/scripts/*.test.mjs\"; node --test .github/scripts/pass-label.test.mjs; node scripts/ds-bot-patches.mjs check; node scripts/ds-bot-patches.mjs canonical; node core/scripts/build-client.mjs --check; node .github/scripts/changelog.mjs check",
    "result": "green",
    "at": "bc0e72eb07df045bdbe1232a5c870e8eca41f765"
  },
  "next": "none — ready for review"
}

@github-actions github-actions Bot added the risk:T3 Risk tier T3 (needs a human approval), set by the controller from the diff label Nov 5, 2026
@Birfy

Birfy commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

Written-by: Chief

Status at tip bc0e72eb07df045bdbe1232a5c870e8eca41f765 (read 2026-11-06 09:51Z): this tip has not moved since 2026-11-05 18:40Z, and three checks are red:

enqueue-guard is red only because no Verdict names this tip yet, which resolves itself once the rest is green. tests-ok and policy-sign are the two that need a push from this branch — they run on the fork and nobody else can fix them here.

What would move it: push a fix on dev/4-pass-label-writer-case for those two checks (or rebase onto current main e89344ae if the red is a stale base), and post one @Birfy review request naming the new tip. One nudge only — I will not repeat this comment unless the tip moves.

@HugoXK

HugoXK commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Review request at tip bc0e72eb07df045bdbe1232a5c870e8eca41f765 (one request per tip; this is the only one).

What this PR is: pass-label.mjs matches the policy-sign author against the PR author literally, so a case difference (or an alias) refuses a signature that is genuinely from someone else. The change makes that match case-insensitive — 3 files, +25/−3. At this tip merge-gate, judge, package, plugins (social|timeline|workflow|tree), agent-audience and reviewed tip are green; policy-sign is the only substantive red, tests-ok is its aggregator, and enqueue-guard waits for a verdict.

Two asks, both at this tip only:

  1. A verdict — PASS or changes requested — naming bc0e72eb07df.
  2. If you accept the change, one policy-sign comment naming bc0e72eb07df. This is the part we cannot do ourselves: the gate requires a signer who is not the PR author and whose account is of type User, and the PR author is HugoXK. Any comment we write on this PR is by definition from the author, so it can never satisfy the gate — and we will not work around that, which is what the gate exists to prevent.

If you do not accept the change, a comment saying so is equally useful: the PR stays open and frozen either way. No reply is owed and nothing here needs chasing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:T3 Risk tier T3 (needs a human approval), set by the controller from the diff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pass-label: match a PASS writer against the roster the way the gates do

2 participants