From be8f0b7a873e981f5c7021b24be3fd0874768762 Mon Sep 17 00:00:00 2001 From: Alex Chao Date: Wed, 16 Sep 2026 01:37:36 +0800 Subject: [PATCH] chore(loop): let workflow_dispatch fall back to the write switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `LOOP_EXECUTE_WRITES: ${{ github.event.inputs.execute_writes || vars.LOOP_EXECUTE_WRITES || 'false' }}` never reached the variable: the input declared `default: 'false'`, so GitHub filled `github.event.inputs.execute_writes` with the non-empty string `'false'` on every manual run and the `||` short-circuited there. Verified on run 35002295453 with the repository variable already set to true — the engine still logged `writeLevel=report` and the payload showed `"execute_writes": "false"`. The effect was narrow but exactly wrong: schedule/issues/pull_request runs (where `github.event.inputs` is null) followed the variable correctly, while the one entry point a human uses to *test* the switch could never exercise it. Dropping the default makes the input tri-state and the expression mean what it reads: unset → fall back to the repository variable; `true`/`false` → override for that run. The description says so now, since "empty follows the variable" is otherwise invisible from the dispatch form. Spotted by the loop's own triage of this PR (run 35003006260, its first `auto` execution): the commit type was `fix(loop)`, which AGENTS.md reserves for changes a package consumer can observe, and changelogen renders into the user-facing CHANGELOG. --- .github/workflows/loop.yml | 3 +-- scripts/loop/README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/loop.yml b/.github/workflows/loop.yml index 729fa43..ec2bc02 100644 --- a/.github/workflows/loop.yml +++ b/.github/workflows/loop.yml @@ -35,9 +35,8 @@ on: required: false default: triage execute_writes: - description: 'L2 rehearsal: set "true" to allow real GitHub writes (default report-only)' + description: 'Override the repo variable for this run: "true" writes, "false" reports. Leave empty to follow vars.LOOP_EXECUTE_WRITES.' required: false - default: 'false' smoke: description: 'Infrastructure only: exercise checkout/install/R2 pull+push, skip the agent' required: false diff --git a/scripts/loop/README.md b/scripts/loop/README.md index 0925a89..b94d262 100644 --- a/scripts/loop/README.md +++ b/scripts/loop/README.md @@ -214,7 +214,7 @@ reason a future reader may see the parameter and wonder where it came from. | `GH_TOKEN` | job env | `github.token`. No PAT exists in the system, so no credential carries the owner's bypass. | | `agentEnv(writeLevel)` | `shared/agent.mjs` | Builds the child environment from scratch: strips the R2 keys (the state bucket is the host's business, not the agent's) and injects a git identity under `auto`. It does **not** hand the agent a weaker token — a job has only one. | | `persist-credentials: false` | the `actions/checkout` step | Keeps the job token out of the repo's git config, where every later `git` invocation would pick it up. Defence in depth, not the mechanism. | -| `vars.LOOP_EXECUTE_WRITES` | job env | `workflow_dispatch` still overrides per run, so the A1 rehearsal entry point is unchanged. | +| `vars.LOOP_EXECUTE_WRITES` | job env | The switch. `workflow_dispatch` can override it per run: leave the input empty to follow the variable, or pass `true`/`false` to force one run. (The input has no `default:` on purpose — a non-empty default like `'false'` short-circuits the `github.event.inputs.x \|\| vars.x` fallback and makes the variable unreachable from the one entry point a human uses to test it, which is exactly what happened before this was fixed.) | | `push` action | `planActions` | `pr-opened` plans `push` → `pr-create` → label/comment. A failure in either of the first two **aborts the chain**, so a PR that never appeared is never labelled. | | branch check | `applyActions` | `loop/-` only — no other ref is pushed, whatever the branch field says. | | dirty-tree check | `applyActions` | A dirty tree is refused: the commit would silently stay behind and the PR would ship an empty diff. |