From c17af94ab8cec9bc64b16d25c0c4477ff1c386eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Aug 2026 14:14:31 +0200 Subject: [PATCH] fix(dor): draft the build PR until acceptance, and un-gate the value-gate notice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three problems, all surfaced by #370 → PR #933, where the requestor said the PR should never have existed because they had not agreed to the solution. 1. The PR was opened ready-for-review on the FIRST build and every feedback round re-advertised "CI green". #933 sat like that through eight rounds of the requestor rejecting the design — one of which added a schema migration. Green checks mean the agent's own tests pass; they say nothing about whether the solution is the one that was asked for, and a green ready-for-review PR reads as mergeable. Open it as a draft; dor-acceptance.yml takes it out of draft on `approve`, the signal it already detects. CI runs on drafts unchanged (no workflow here filters on draft), so verify_loop is unaffected — the only thing a draft cannot do is merge. Branch protection and the human merge review are untouched. 2. The value gate asked the wrong person the wrong question. Its notice was a hardcoded @-list and its framing was purely spend ("nothing runs or spends until you do"); it never showed the spec, which by then was days up-thread. On #370 a maintainer approved and the PR then claimed it was built "from the approved spec" — while the requestor had never confirmed it. Address the requestor of record (authorize already resolves it; now exported), deep-link the certified spec, and ask whether it describes the solution they want. Anyone may still approve so an absent requestor cannot stall a build — the gate now records who did and says plainly when it was not the requestor. 3. #977 moved that notice INTO the `gate` job, which holds `environment: build-approval`. A job gated by required reviewers runs no step until approved, so the notice could only arrive after the approval it was asking for: an issue needing the gate would wait with nothing said on it. Latent so far — the one build since #977 took the autonomous path and skipped the gate. Split into an ungated `notify` job (asks) and the gated `gate` job (records, post-approval by construction). test/ci-scripts/test-dor-gate-notice.sh guards all three structurally, including the exact #977 shape: the job posting the notice must carry no `environment:`. 12 tests; 9 fail against the pre-change tree. Wired into the existing ci-scripts job in pr.yml. Co-Authored-By: Claude Opus 5 (1M context) --- .github/scripts/dor_build_flow.sh | 11 ++- .github/workflows/dor-acceptance.yml | 13 ++- .github/workflows/dor-build-agent.yml | 62 ++++++++++++- .github/workflows/pr.yml | 1 + changes/dor-draft-pr-and-gate-notify.md | 3 + test/ci-scripts/test-dor-gate-notice.sh | 112 ++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 changes/dor-draft-pr-and-gate-notify.md create mode 100644 test/ci-scripts/test-dor-gate-notice.sh diff --git a/.github/scripts/dor_build_flow.sh b/.github/scripts/dor_build_flow.sh index c48da4244..412bfa6f7 100644 --- a/.github/scripts/dor_build_flow.sh +++ b/.github/scripts/dor_build_flow.sh @@ -195,11 +195,18 @@ Leave your changes in the working tree — do NOT commit, push or open a PR.%s' fi # 2. Open the PR (BOT token — GITHUB_TOKEN can't create PRs here). +# +# DRAFT, deliberately. A ready-for-review PR with green checks reads as "this can go to main", and +# for an agent-built change that is a lie: CI green means the agent's own tests pass, not that the +# requestor accepted the solution. #933 sat non-draft and green through EIGHT rounds of the +# requestor rejecting the design. dor-acceptance.yml marks it ready the moment they reply `approve`. +# CI runs on drafts exactly as on any PR (no workflow here filters on draft), so verify_loop below +# is unaffected — the only thing a draft cannot do is merge. pr=$(gh pr list --repo "$REPO" --head "$BRANCH" --state open --json number --jq '.[0].number // empty') if [ -z "$pr" ]; then - pr=$(GH_TOKEN="$BOARD_TOKEN" gh pr create --repo "$REPO" --base main --head "$BRANCH" \ + pr=$(GH_TOKEN="$BOARD_TOKEN" gh pr create --repo "$REPO" --base main --head "$BRANCH" --draft \ --title "$(gh issue view "$ISSUE" --repo "$REPO" --json title --jq '.title')" \ - --body "$(printf 'Closes #%s\n\nBuilt autonomously by the DoR build agent from the approved spec. Functional-test env: %s\n\nDo not merge until CI is green and the requestor has accepted.' "$ISSUE" "$URL")" \ + --body "$(printf 'Closes #%s\n\n> **Requestor acceptance: not yet.** This PR is a draft until the requestor replies `approve` on #%s. It becomes ready for review then, and not before.\n\nBuilt autonomously by the DoR build agent from the certified spec. Functional-test env: %s\n\nGreen checks here mean the agent'\''s own tests pass — they say nothing about whether the solution is the one that was asked for.' "$ISSUE" "$ISSUE" "$URL")" \ | grep -oE '[0-9]+$') || bail "could not open the PR" fi claim_sidekick "$pr" # ~/.dor-reservation + the sk: