Merge-robot fail-loud discharge: identity check, refusals fail the job (bug-fix contract first customer) #211

Merged
conductor merged 1 commits from merge-robot-fix into master 2026-09-07 20:46:27 +01:00
Owner

Summary

  • Bug-fix contract's first customer: the merge-robot's silent no-op (green runs, satisfied merge conditions, zero merges, no error) is discharged red-first.
  • Root-cause findings: (1) merge refusals were print-and-continue (exit 0) — the failure mode henxels' own doctrine calls "a silent pass is a defect"; (2) no token-identity verification — a scoped-actions-token 403 was indistinguishable from "nothing to do"; (3) inline untestable script.
  • Fix: logic extracted to scripts/merge_robot.py (testable); identity verified FIRST (GET /user, logged); merge refusals (403 scope, unexpected 405, URLError) FAIL THE JOB with full error body; "behind the base branch" 405 correctly a skip, not a crash; every PR produces a decision line; workflow_dispatch added for on-demand runs.
  • Frozen tests (9): identity-first ordering, 403/405 refusals raise + main exits 1, success merges, pending/conflict/behind skip without POST, exit 0 path. Test doubles simulate the SERVER contract (mergeable flag included) — the circularity the spec-gate warned about, avoided.
  • Workflow-contract tests assert the wiring; the discharge record for this fix lives in this PR body (Discharge: robot-noop -> tests/test_merge_robot.py).

Verification

  • Suite 613+84 green (604 baseline + 9); ratchet PASS; ruff clean; henxels exit 0; workflow YAML parses.
  • Live acceptance: after merge, the next robot run against the queued green PRs (#205/#206/#207/#208/#209/#210) must show identity + per-PR decisions, and any refusal must fail the run visibly.
## Summary - Bug-fix contract's first customer: the merge-robot's silent no-op (green runs, satisfied merge conditions, zero merges, no error) is discharged red-first. - Root-cause findings: (1) merge refusals were print-and-continue (exit 0) — the failure mode henxels' own doctrine calls "a silent pass is a defect"; (2) no token-identity verification — a scoped-actions-token 403 was indistinguishable from "nothing to do"; (3) inline untestable script. - Fix: logic extracted to `scripts/merge_robot.py` (testable); identity verified FIRST (GET /user, logged); merge refusals (403 scope, unexpected 405, URLError) FAIL THE JOB with full error body; "behind the base branch" 405 correctly a skip, not a crash; every PR produces a decision line; `workflow_dispatch` added for on-demand runs. - Frozen tests (9): identity-first ordering, 403/405 refusals raise + main exits 1, success merges, pending/conflict/behind skip without POST, exit 0 path. Test doubles simulate the SERVER contract (mergeable flag included) — the circularity the spec-gate warned about, avoided. - Workflow-contract tests assert the wiring; the discharge record for this fix lives in this PR body (Discharge: robot-noop -> tests/test_merge_robot.py). ## Verification - Suite 613+84 green (604 baseline + 9); ratchet PASS; ruff clean; henxels exit 0; workflow YAML parses. - Live acceptance: after merge, the next robot run against the queued green PRs (#205/#206/#207/#208/#209/#210) must show identity + per-PR decisions, and any refusal must fail the run visibly.
conductor added 1 commit 2026-09-07 18:14:35 +01:00
fix(pipeline): merge-robot fails loudly on refusals, verifies token identity, extracted testable script — red-first discharge of the silent no-op (bug-fix contract) (#147)
Auto-label / priority-gate (pull_request) Skipped
Auto-label / auto-label (pull_request) Successful in 2s
CI Pipeline / lint (push) Successful in 24s
CI Pipeline / unit-tests (push) Successful in 32s
CI Pipeline / canary (push) Successful in 26s
CI Pipeline / best-practices (push) Successful in 2s
CI Pipeline / documentation (push) Successful in 2s
CI Pipeline / type-check (push) Successful in 22s
CI Pipeline / gitea-offline (push) Successful in 13s
CI Pipeline / required-checks (push) Skipped
CI Pipeline / lint (pull_request) Successful in 23s
CI Pipeline / unit-tests (pull_request) Successful in 31s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / best-practices (pull_request) Successful in 3s
CI Pipeline / documentation (pull_request) Successful in 2s
CI Pipeline / type-check (pull_request) Successful in 21s
CI Pipeline / gitea-offline (pull_request) Successful in 13s
CI Pipeline / required-checks (pull_request) Successful in 0s
7402a68095
gitea-actions Bot added the bugidentity labels 2026-09-07 18:14:40 +01:00
conductor merged commit de8c7a6e47 into master 2026-09-07 20:46:27 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: conductor/rune#211