staging → main: auto-promote 173e22e - #2570
Merged
Merged
Conversation
The workflow_dispatch input default and the workflow_run env fallback both pointed at 'hongmingwang', which doesn't match any current prod tenant (slugs are: hongming, chloe-dong, reno-stars). CP silently skipped the missing canary and put every tenant in batch-1 in parallel, defeating the canary-first soak gate that exists to catch image-boot regressions before they hit the whole fleet. Concrete example from today's c0838d6 redeploy at 11:53Z (run 25278434388): the dispatched body was `{"target_tag":"staging-c0838d6","canary_slug":"hongmingwang",...}` and the CP response showed all 3 tenants in `"phase":"batch-1"` — no soak, no canary. The deploy happened to be safe, but a broken image would have hit hongming + chloe-dong + reno-stars simultaneously. Fixed in three places: the runtime ordering comment, the workflow_dispatch default, and the env fallback used by the workflow_run trigger. Comment documents the rationale so the next slug rename doesn't silently regress this again. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore: sync main → staging (auto, ff to c0838d6)
ci(redeploy): fix stale canary_slug default 'hongmingwang' → 'hongming'
github-actions
Bot
requested a review
from hongmingwang-moleculeai
as a code owner
May 3, 2026 12:17
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
… (CR2 10782)
CR2 review 10782 found a FAIL-OPEN security defect in
.gitea/scripts/reserved-path-review.sh: the previous if/else
around `reserved_paths_match_any` treated any non-zero return code
as 'no match' (success, gate N/A). But the matcher's contract is:
return 0 = a reserved path matched
return 1 = clean, no reserved path matched
return 2 = ERROR: manifest missing / invalid / empty
Lumping 2 in with 1 meant a missing/empty/invalid .gitea/reserved-paths.txt
silently allowed reserved-path changes through, defeating the guard's
purpose (CR2 10782: 'FAIL-OPEN: missing manifest -> spurious success').
Fix: branch explicitly on the matcher's exit code via a case statement.
0 -> reserved path matched, continue to step 4 (non-author approval check)
1 -> no match, post success, exit 0
* -> ERROR (incl. 2, plus any other non-0/1 from a future matcher
version), post failure, log 'reserved-paths.txt missing/invalid —
failing closed', exit 1. Do NOT pass on error.
The DETECTIVE backstop (audit-force-merge.sh) is intentionally
fail-OPEN-by-design per its own header and is unchanged. The
PREVENTIVE gate (this script) is now fail-CLOSED on every manifest-error
path.
Adds .gitea/scripts/tests/test_reserved_path_review.sh (regression lock):
T1 manifest missing -> posts failure (RC=2 -> FAIL-CLOSED)
T2 manifest empty -> posts failure (RC=2 -> FAIL-CLOSED)
T3 manifest comments-only -> posts failure (RC=2 -> FAIL-CLOSED)
T4 no match (RC=1) -> posts success (N/A) — existing pass case
T5 match (RC=0) -> no status post, continues to step 4
T6/T6b contract pins — locks the explicit case-on-MATCH_RC pattern and
fails if the old 'if MATCHES=$(...)' FAIL-OPEN shape returns
T6c log-line check — 'reserved-paths.txt missing/invalid' + 'failing closed'
T7 bash -n syntax check on the live script
All 9 tests pass locally. The matcher's RC=2 contract is also confirmed
end-to-end against the real reserved-path-match.sh matcher (missing
manifest / empty manifest / comments-only manifest all return 2 with
the documented ::error stderr line).
Head unchanged on the same #2570 branch (chore/core-self-merge-guard-reserved-paths,
head 57557d8c) so the 1-distinct CR-A approval from agent-researcher
(04:43Z) is preserved.
CR2 10782 fix; spec-only execution.
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
…2 10782 follow-up) Augments the prior fail-CLOSED fix on reserved-path-review.sh (76a8a057). Researcher adjudication (job 467485/run 346968, on molecule-runner-robot-1-4 image CACHED — confirmed NOT infra) found a SECOND defect: the workflow checks out the BASE ref (f44d688) and runs `bash .gitea/scripts/ reserved-path-review.sh`, but #2570 is the PR that INTRODUCES that script — so on this PR the script is ABSENT on base → 'No such file or directory', the check hard-fails. This is a bootstrap / self-reference problem: the guard gates the very PR that adds the guard. Unfixable without a workflow change. Fix: refine the checkout strategy in the workflow to break the self-reference while preserving the security model: 1. The SCRIPT is now checked out from the PR HEAD (not base), so the gate is always present — including on the bootstrap PR that adds the gate. `actions/checkout` uses `ref: ${{ github.event.pull_request.head.sha }}` for this. (`pull_request_target` ensures the run runs with the BASE commit's permissions, not the PR's — so the PR author cannot inject code that runs in the workflow's auth context. The head checkout is for FILE READING only.) 2. The reserved-paths MANIFEST (.gitea/reserved-paths.txt) is read from the BASE branch via `git show <base.sha>:.gitea/reserved-paths.txt` and staged to .gitea/reserved-paths.txt in the workspace. This preserves the original security intent: a PR author cannot widen the gate by adding new reserved patterns in their own PR (the manifest is base-sourced for every steady-state PR). 3. Bootstrap PR fallback: if `git show` on the base manifest fails (the single PR that INTRODUCES the manifest — base has no file yet), the workflow falls back to the head's manifest and emits a loud `::notice::` log line so reviewers see the bootstrap path ran. The script still executes — this is NOT an unconditional pass; it is a graceful one-time bootstrap. 4. The script is invoked with `RESERVED_PATHS_FILE: .gitea/reserved-paths.txt` so it uses the (base-overridden or head-fallback) manifest we just staged — not whatever the script's own RESERVED_PATHS_FILE default resolves to. 5. The DETECTIVE backstop (audit-force-merge.sh emitting incident.reserved_self_merge) is unchanged — intentionally fail-OPEN-by-design per its own header. New regression tests (5 added on top of the prior 9, now 14 total): T6d: workflow checks out PR HEAD (so the gate script is present, including on the bootstrap PR) T6e: workflow fetches .gitea/reserved-paths.txt from BASE via git show (security model preserved) T6f: workflow logs the bootstrap fallback explicitly T6g: workflow does NOT have an unconditional pass shortcut (re-introduce-fail-open guard) T6h: workflow passes RESERVED_PATHS_FILE explicitly to the script ALL 14 TESTS PASS locally. Combined with the prior fix at 76a8a057: Defect #1 (CR2 10782, fail-OPEN return-code): CLOSED at 76a8a057 (script now branches on MATCH_RC explicitly; 0/1/2 with 2+ failing closed; 9 regression tests lock the contract). Defect #2 (Researcher adjudication, bootstrap / self-reference): CLOSED here (workflow now checks out PR HEAD + reads base manifest via git show + bootstrap fallback for the introducing PR; 5 new regression tests lock the contract). Head moves from 76a8a057 to (new) on the same chore/core-self-merge-guard-reserved-paths branch. The CR-A approval chain (agent-researcher 04:43Z) and CR2 REQUEST_CHANGES (10782, also from agent-researcher) are against the prior head 57557d8c — they will need to re-review this new head. Spec-only execution — no review/decisions, no self-merge. CR2 10782 fix (this is the augmented 03744380).
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
Relocate the bp-exempt / bp-required directive comments to within the linter's 3-line window above their job keys. Comment-only relocation; no workflow logic/steps changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
, RC 10917) The gate-asset bootstrap fetched only reserved-path-review.sh, but that script `source`s reserved-path-match.sh — missing on base for the introducing PR, so the job died with "reserved-path-match.sh: No such file or directory". The manifest fallback also only LOGGED instead of fetching head's reserved-paths.txt. Fix: bootstrap-fetch the SCRIPT, its sourced HELPER, and the MANIFEST from PR head when (and only when) base lacks them. Steady-state base.sha checkout and base-owned security model unchanged (no self-bypass). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Jun 12, 2026
… CTO-reserved paths (core mirror, cp#673 precedent)' (#2570) from chore/core-self-merge-guard-reserved-paths into main
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated promotion of
staging(173e22e0) tomain. All required staging gates green at this SHA: CI, E2E Staging Canvas, E2E API Smoke, CodeQL.This PR is auto-generated by
.github/workflows/auto-promote-staging.ymlwhenever every required gate completes green on the same staging SHA. It exists because main's branch protection requires status checks "set by the expected GitHub apps" — directgit pushfrom a workflow can't satisfy that, only PR merges through the queue can.Merge queue lands this; no human action needed unless gates fail. Reverse-direction sync (the merge commit on main → staging) is handled by
auto-sync-main-to-staging.yml.