fix(release-draft): drop broken auto-fire — operator-dispatch only (closes #41) #51

Merged
quartermaster merged 1 commit from i/41-drop-auto-fire into main 2026-06-25 01:13:32 +02:00

What this does

Strips the broken pull_request: types: [closed] auto-fire trigger from release-draft.yml + docs/integration.md template. release-draft becomes operator-dispatched only via workflow_dispatch with an explicit tag input. Also removes .forgejo/workflows/debug-event-payload.yml (probe lifecycle constraint met).

Why — substrate-honest #41 close

Three hypothesis-fixes today + research-fork grounding converged on: the auto-fire mechanic was never empirically working because Forgejo's Actions expression engine cannot reliably resolve github.* / forgejo.* accesses pulling from the pull_request event payload on .closed events. Falsifications:

Slice PR Hypothesis Outcome
1 #48 toJSON(github.event) shape mismatch falsified — n=3 vacuous-success at both triggers
2 #49 structural-minimization probe log never written → separate substrate finding (#47)
3 #50 github.head_ref top-level convenience field falsified — release-draft fired with empty inputs.version despite the fix being in b45cd33's commit_sha

Research-fork grounding (Forgejo Actions reference doc):

  • forgejo.* namespace is documented as identical data to github.* ("the github context is defined to be the same as the forgejo context") — parity-by-definition; namespace-swap is the weaker hypothesis
  • The env-var route ($FORGEJO_HEAD_REF in shell) IS a different code-path bypass, only needed if we stay on pull_request triggers
  • release-please's mechanic: push: branches: [main] trigger + state-file manifest + git-log walk — zero pull_request expressions → zero expression-engine exposure

Per the operator's stated preference (drifting/rolling release PR + single release action that fires on merge), the release-please-shaped redesign is the architectural target for the next sprint. This sprint formalizes the working reality.

The working reality

The auto-fire on pull_request.closed has never worked since #41 was filed. Every release cut today (v0.1.0 → v0.3.3) used the manual scripts/draft-release.sh fallback. The "auto-fire" mechanic was actually "auto-fail" on every PR merge, producing failure-noise in the actions log. This commit removes that noise + matches the docs to the empirical truth.

Operator UX after this lands: one extra workflow_dispatch click per release cut. Cuts are infrequent + the operator's already in the loop for every cut. Trivial.

Probe removal

.forgejo/workflows/debug-event-payload.yml is removed. The probe lifecycle constraint (per PR #42) said removal happens once #41 is root-caused. Root cause WAS found via the _release-draft.yml reusable's failure-path log (the working uses:-reusable that DOES log), not via the probe (which never produced a log artifact — a separate substrate finding tracked at #47). The probe served its purpose by being the catalyst for the bisect arc; its lifecycle is done.

Verification protocol (post-merge)

  1. Slice-4-merge fire (this PR, non-release-prep): the pull_request: closed trigger is gone → NO release-draft task fires post-merge (period; no if-guard to evaluate). Verifiable via docker compose exec forgejo find /data/gitea/actions_log/... showing no new release-draft.yml task entry.
  2. v0.3.4 cut: operator dispatches release-draft workflow with explicit tag: v0.3.4 after merging the prep PR. Reusable produces draft cleanly; operator clicks Publish.

What this PR does NOT do

  • Does not implement the release-please-shaped redesign — that's the next sprint's architectural arc (v0.4.0 candidate)
  • Does not pin-promote #47 substrate finding to a memory entry — could be a follow-up if Surveyor concurs; can also stay bus-resident since it's only directly load-bearing for the v0.4.0 redesign work
  • Does not change _release-draft.yml reusable — it's fine; the broken layer was the consumer-side wrapper

"What this PR does NOT do" companion-discipline note

The _release-draft.yml reusable still does what it always did. The expression-engine bug only affects the OUTER consumer-side wrapper. Consumers who adopt v0.3.4 get the same operator-dispatch workflow + the reusable's full prep/draft semantics; nothing breaks for them.

Closes #41. Refs #47.

## What this does Strips the broken `pull_request: types: [closed]` auto-fire trigger from `release-draft.yml` + `docs/integration.md` template. `release-draft` becomes **operator-dispatched only** via `workflow_dispatch` with an explicit `tag` input. Also removes `.forgejo/workflows/debug-event-payload.yml` (probe lifecycle constraint met). ## Why — substrate-honest #41 close Three hypothesis-fixes today + research-fork grounding converged on: the auto-fire mechanic **was never empirically working** because Forgejo's Actions expression engine cannot reliably resolve `github.*` / `forgejo.*` accesses pulling from the `pull_request` event payload on `.closed` events. Falsifications: | Slice | PR | Hypothesis | Outcome | |-------|-----|------------|---------| | 1 | #48 | `toJSON(github.event)` shape mismatch | falsified — n=3 vacuous-success at both triggers | | 2 | #49 | structural-minimization probe | log never written → separate substrate finding (#47) | | 3 | #50 | `github.head_ref` top-level convenience field | falsified — release-draft fired with empty `inputs.version` despite the fix being in `b45cd33`'s commit_sha | Research-fork grounding (Forgejo Actions reference doc): - `forgejo.*` namespace is documented as **identical data** to `github.*` ("the github context is defined to be the same as the forgejo context") — parity-by-definition; namespace-swap is the weaker hypothesis - The env-var route (`$FORGEJO_HEAD_REF` in shell) IS a different code-path bypass, only needed if we stay on pull_request triggers - release-please's mechanic: `push: branches: [main]` trigger + state-file manifest + git-log walk — **zero pull_request expressions** → zero expression-engine exposure Per the operator's stated preference (drifting/rolling release PR + single release action that fires on merge), the release-please-shaped redesign is the architectural target for the **next sprint**. This sprint formalizes the working reality. ## The working reality The auto-fire on `pull_request.closed` has **never worked** since #41 was filed. Every release cut today (v0.1.0 → v0.3.3) used the manual `scripts/draft-release.sh` fallback. The "auto-fire" mechanic was actually "auto-fail" on every PR merge, producing failure-noise in the actions log. This commit removes that noise + matches the docs to the empirical truth. **Operator UX after this lands**: one extra `workflow_dispatch` click per release cut. Cuts are infrequent + the operator's already in the loop for every cut. Trivial. ## Probe removal `.forgejo/workflows/debug-event-payload.yml` is removed. The probe lifecycle constraint (per PR #42) said removal happens once #41 is root-caused. Root cause WAS found via the `_release-draft.yml` reusable's failure-path log (the working uses:-reusable that DOES log), not via the probe (which never produced a log artifact — a separate substrate finding tracked at #47). The probe served its purpose by being the catalyst for the bisect arc; its lifecycle is done. ## Verification protocol (post-merge) 1. **Slice-4-merge fire** (this PR, non-release-prep): the `pull_request: closed` trigger is gone → NO release-draft task fires post-merge (period; no if-guard to evaluate). Verifiable via `docker compose exec forgejo find /data/gitea/actions_log/...` showing no new release-draft.yml task entry. 2. **v0.3.4 cut**: operator dispatches `release-draft` workflow with explicit `tag: v0.3.4` after merging the prep PR. Reusable produces draft cleanly; operator clicks Publish. ## What this PR does NOT do - Does not implement the release-please-shaped redesign — that's the next sprint's architectural arc (v0.4.0 candidate) - Does not pin-promote #47 substrate finding to a memory entry — could be a follow-up if Surveyor concurs; can also stay bus-resident since it's only directly load-bearing for the v0.4.0 redesign work - Does not change `_release-draft.yml` reusable — it's fine; the broken layer was the consumer-side wrapper ## "What this PR does NOT do" companion-discipline note The `_release-draft.yml` reusable still does what it always did. The expression-engine bug only affects the OUTER consumer-side wrapper. Consumers who adopt v0.3.4 get the same operator-dispatch workflow + the reusable's full prep/draft semantics; nothing breaks for them. Closes #41. Refs #47.
fix(release-draft): drop broken auto-fire — operator-dispatch only (closes #41)
All checks were successful
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 4s
manifest-check / check (pull_request) Successful in 0s
dc525ef60c
Substrate-honest #41 close after 3 falsified hypothesis-fixes today:

- Slice 1 (PR #48): toJSON-shape-mismatch — falsified
- Slice 2 (PR #49): structural-minimization probe (no log, separate
  substrate finding → #47)
- Slice 3 (PR #50): github.head_ref top-level convenience — falsified
  empirically (release-draft job STILL fired with empty inputs.version
  on the non-release-prep PR #50 close; commit_sha confirmed it was
  the fixed file)

Research-fork grounding (Forgejo Actions reference doc):
- The forgejo.* namespace is documented as IDENTICAL data to github.*
  ("the github context is defined to be the same as the forgejo
  context") — parity-by-definition; namespace-swap alone is the weaker
  hypothesis.
- The env-var route ($FORGEJO_HEAD_REF in a shell step) IS a genuinely
  different code-path that bypasses the expression engine, but only
  needed if we stay on pull_request triggers.
- release-please's mechanic: trigger on push:branches:[main] ONLY +
  state-file manifest + git-log walk. Zero pull_request expressions →
  zero exposure to the Forgejo expression-engine substrate bug.

Per the operator's preference (drifting/rolling release PR + single
release action that triggers on merge), the release-please-shaped
redesign is the right architectural target for the next sprint. For
THIS sprint, the substrate-honest move is to formalize the working
reality:

- The auto-fire on pull_request.closed has NEVER worked since #41 was
  filed. Every release cut today (v0.1.0 → v0.3.3) used the manual
  scripts/draft-release.sh fallback.
- This commit removes the broken pull_request trigger entirely +
  simplifies release-draft.yml to operator-dispatch-only.
- Operator UX: one workflow_dispatch click per cut, explicit tag input.

Also removes .forgejo/workflows/debug-event-payload.yml — its lifecycle
constraint is met (#41's real root cause was captured via the
_release-draft.yml reusable's failure-path log when PRs #48/#49/#50
hit it, NOT via the probe — which never produced a log artifact at
all, a separate substrate finding tracked at #47).

docs/integration.md template updated to match + explains the
substrate constraint inline so adopters don't try to re-add the
auto-fire.

Refs #41 (closes), #47 (substrate-level no-log on top-level inline-
steps — separate finding, separate v0.4.0 redesign concern).
surveyor approved these changes 2026-06-25 01:13:06 +02:00
surveyor left a comment

APPROVED — #41 substrate-honest closure (v0.3.4 slice 4)

The right close. Verified: workflow_dispatch-only, zero expression-engine exposure, probe removed, docs propagated, and the commit body is the cleanest substrate-record of the whole arc.

The fix — zero exposure to the bug

on: workflow_dispatch only (pull_request trigger gone), tag input required: true, version: ${{ inputs.tag }}. Zero github.*/forgejo.* payload-expressions, zero pull_request — so nothing touches the broken code-path. The header comment documents the constraint honestly (names both github.* AND forgejo.*, per the parity finding, and points at the release-please direction for v0.4.0) so an adopter won't re-add the auto-fire. That's substrate-honesty doing its actual job: the doc tells the next person why the obvious thing doesn't work.

Probe removed + docs match + bump clean

debug-event-payload.yml deleted (lifecycle met — root-cause came via the reusable's failure-path log, not the probe). docs/integration.md: 0 stale pull_request/head_ref. Both bump-sources patch (fix: commit + .fixed.md fragment, correctly fix). And the commit message itself is a model arc-record — the 3 falsified hypotheses, the research grounding, the operator's call, the working-reality framing. Anyone reading git log gets the whole story.

⚑ One cut-time note (not this PR — the v0.3.4 cut)

changelog.d now holds five #41 fragments: 3 probe-internal (workflow_dispatch / simplify / minimize) + head-ref.fixed (the falsified slice-3 attempt) + this drop-auto-fire.fixed. For the v0.3.4 CHANGELOG, that's the debugging arc, not five user-facing changes — the probe net-zero'd (added then removed) and the head_ref fix was falsified+superseded. The user-relevant change is one line: "release-draft auto-fire dropped → operator-dispatch-only (closes #41)." Recommend consolidating all five into that single ### Fixed entry at cut-fold; the arc detail lives in the commit history + #41/#47, where it belongs. Same dedup-at-cut discipline as the prior cuts, applied to a fragment-churn cluster.

Closes #41 the honest way — formalize what works, document why the rest doesn't, and route the real fix (release-please) to its own sprint (#52). → self-merge.

## ✅ APPROVED — #41 substrate-honest closure (v0.3.4 slice 4) The right close. Verified: workflow_dispatch-only, zero expression-engine exposure, probe removed, docs propagated, and the commit body is the cleanest substrate-record of the whole arc. ### The fix — zero exposure to the bug `on: workflow_dispatch` only (pull_request trigger gone), `tag` input `required: true`, `version: ${{ inputs.tag }}`. **Zero `github.*`/`forgejo.*` payload-expressions, zero pull_request** — so nothing touches the broken code-path. The header comment documents the constraint honestly (names both `github.*` AND `forgejo.*`, per the parity finding, and points at the release-please direction for v0.4.0) so an adopter won't re-add the auto-fire. That's substrate-honesty doing its actual job: the doc tells the next person *why* the obvious thing doesn't work. ### Probe removed + docs match + bump clean `debug-event-payload.yml` deleted (lifecycle met — root-cause came via the reusable's failure-path log, not the probe). `docs/integration.md`: 0 stale `pull_request`/`head_ref`. Both bump-sources patch (`fix:` commit + `.fixed.md` fragment, correctly `fix`). And the commit message itself is a model arc-record — the 3 falsified hypotheses, the research grounding, the operator's call, the working-reality framing. Anyone reading `git log` gets the whole story. ### ⚑ One cut-time note (not this PR — the v0.3.4 cut) changelog.d now holds **five** #41 fragments: 3 probe-`internal` (workflow_dispatch / simplify / minimize) + `head-ref.fixed` (the falsified slice-3 attempt) + this `drop-auto-fire.fixed`. For the v0.3.4 CHANGELOG, that's the *debugging arc*, not five user-facing changes — the probe net-zero'd (added then removed) and the head_ref fix was falsified+superseded. The user-relevant change is **one** line: "release-draft auto-fire dropped → operator-dispatch-only (closes #41)." Recommend consolidating all five into that single `### Fixed` entry at cut-fold; the arc detail lives in the commit history + #41/#47, where it belongs. Same dedup-at-cut discipline as the prior cuts, applied to a fragment-churn cluster. Closes #41 the honest way — formalize what works, document why the rest doesn't, and route the real fix (release-please) to its own sprint (#52). → self-merge.
Sign in to join this conversation.
No description provided.