Skip to content

night: a red night check opens or updates one issue; RELEASE step 2 reads the nightly first (PMAT-2174, PMAT-2175) - #2176

Merged
noahgift merged 2 commits into
mainfrom
PMAT-2174-night-issue
Oct 15, 2026
Merged

noahgift merged 2 commits into
mainfrom
PMAT-2174-night-issue

Conversation

@noahgift

Copy link
Copy Markdown
Contributor

Follow-ups from the #2171 reviews. Refs #2174, Refs #2175.

PMAT-2174: a red night check opens or updates one issue. The ci.yml comment already said this happens, but no step did it.

  • New local action .github/actions/night-issue/action.yml. It is the last step of all seven night-only jobs, under if: failure() && github.event_name == 'schedule'.
  • It finds the open issue titled night: <job id> red on main and comments on it with the run link, or creates that issue assigned to the one owner.
  • It runs only after its job has failed, so it never changes a job result. The script refuses any event other than schedule. A failed issue lookup fails the step and creates nothing, so there are no duplicate issues.
  • The night jobs get permissions: contents: read, issues: write.
  • night_checks_off_pr_path.rs gets 6 new tests. Two of them run the script against a fake gh.

PMAT-2175: RELEASE.md §5 step 2 reads the nightly first. It reads the scheduled ci.yml run on the pinned SHA, waits for it if it is still in progress, and dispatches only if there is no scheduled run. release_runbook_facts_witness pins the order.

Evidence

  • Red first: on the old ci.yml, 6 of 10 tests fail. A pull_request variant fails the step test, and a permissive script fails the event test. The new RELEASE test fails on the old RELEASE.md.
  • Quorum 3/3 PASS, bound to 3ef97e5 (diff_sha256 c201da3c…). Lanes: sonnet-5-5, haiku-4-5, gemini-3.8-flash-high.
  • Planted control (issue step allowed on pull_request): 3/3 FAIL, and every lane cited the planted lines.

🤖 Generated with Claude Code

Noah Gift and others added 2 commits October 15, 2026 04:12
…l described did not exist (Refs #2174)

ci.yml's TWO-STATE CI comment said a red night job "opens or updates one
issue with one owner", and no step did. Each of the seven night jobs now
ends with the local composite action .github/actions/night-issue under
  if: failure() && github.event_name == 'schedule'
It finds the open issue titled exactly `night: <job id> red on main`,
comments the run on it, or creates it assigned to the action's one owner.
It runs only after its job has already failed, so it cannot change a job's
result; the script refuses every event but `schedule` before calling gh,
so pull_request, merge_group, push and workflow_dispatch file nothing. A
failed lookup fails the step and creates nothing (no duplicate on an API
error). The night jobs get `permissions: contents: read, issues: write`.

XPILE-NIGHT-CHECKS-001 gains assertions 6-7: the issue step is the LAST
step of every night job with exactly that if:, its own job id as check:,
issues: write; no other job calls it; one owner; and the script is
EXECUTED against a stub gh (refusal on five non-schedule events, comment
on an exact title, create on a near-miss, fail on a failed lookup).
RED arms, measured: on the pre-change ci.yml 6 of 10 tests fail; the
planted control (issue step if: also true on pull_request) fails
every_night_job_ends_by_filing_its_one_issue; letting the script accept
pull_request fails the_issue_script_refuses_every_event_but_schedule.

PMAT-Ticket: PMAT-2174
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pinned SHA and dispatches only if there is none (Refs #2175)

Since #2167 ci.yml runs on main every night, so on a frozen Friday the
pinned SHA normally already has a scheduled run. Step 2 used to dispatch
ci and wait unconditionally. It now reads
  gh run list --workflow ci.yml --event schedule --commit <PINNED_SHA>
first, waits for that run if it is still in progress, and dispatches only
when no night has run on the pinned SHA; the check-runs read is unchanged.

release_runbook_facts_witness gains
release_step_2_reads_the_scheduled_run_before_it_dispatches: inside §5
step 2 the scheduled read on <PINNED_SHA> precedes the fallback dispatch,
the dispatch is conditional, and ci.yml still has a schedule: trigger.
RED on the previous RELEASE.md.

PMAT-Ticket: PMAT-2175
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

APPROVE — seat 1, aprender-a7, head 3ef97e5

Read the full diff at 3ef97e5 (action.yml, ci.yml, both tests, RELEASE.md, roadmap). CI is green on this head: gate and workspace-test both pass, and the 7 night jobs are skipped on pull_request as intended.

  • The issue step is the last step of each of the 7 night jobs, under if: failure() && github.event_name == 'schedule'. The script refuses every event but schedule before it calls gh, so a PR, a merge group or a dispatch files nothing. The tests pin this, including the empty event.
  • issues: write is set per night job only. No required job gained permissions, an if: or a needs: on a night job.
  • Exactly one issue per check. The search narrows and the exact-title match decides, so a near-miss title gets no comment. A failed gh issue list fails under set -e before any create, so no duplicate is filed. Inputs reach the script through env: only, with no ${{ }} in run.
  • RELEASE §5 step 2 reads the latest scheduled run on the pinned SHA first, waits if it is still running, and dispatches only when there is none. The witness test pins this.

Note, not blocking: in license-scan the raw cargo deny step is continue-on-error, so only the NOTICE tripwire can open that job's issue. This matches the job's documented design.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

seat 2, aprender-clerk @3ef97e55b9 — APPROVE

Reviewed b70af72 + 3ef97e5; no commits of mine. Required gate and workspace-test are green on this head.

  • .github/actions/night-issue: refuses every event except schedule (exit 2) before any gh call. It finds the issue by exact-title comparison after the search, so a near-miss title does not count. A failed list fails the step under set -e, so it never makes a duplicate. One owner by default.
  • ci.yml: each of the seven night jobs ends with the issue step under if: failure() && github.event_name == 'schedule'. They get issues: write at job level only, and the required jobs are untouched. The step runs only after its job has already failed, so it cannot change any result.
  • Tests: night_checks_off_pr_path.rs pins that the issue step is last, carries no continue-on-error, and that only night jobs file issues. It also drives the script with a fake gh for refusal, the exact-title match, the near-miss and a failed lookup. release_runbook_facts_witness.rs pins that step 2 reads before it dispatches, that the dispatch is conditional, and that the schedule trigger exists.
  • RELEASE.md §5 step 2 now reads the scheduled run on <PINNED_SHA> first and dispatches only if there is none, which addresses my #2171 note.

Non-blocking: license-scan's cargo deny check licenses bans sources step keeps its existing continue-on-error: true. A deny finding therefore never fails the job and never files a night issue; only the NOTICE drift tripwire can. If the deny report is meant to reach an owner, that needs a follow-up.

@noahgift
noahgift merged commit 850ffff into main Oct 15, 2026
11 checks passed
@noahgift
noahgift deleted the PMAT-2174-night-issue branch October 15, 2026 04:44
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.

1 participant