ci(release): drop a dispatch that can only fail - #3325
Conversation
Refs #3316 release.yml was on the never-green list and should not have been. Run 33180327861 on 2026-08-28 SUCCEEDED, publishing t27c 0.2.0. Of the two recent failures, 33230021436 is a `release` event whose tag ("FPGA bitstreams -- 43 syntheses, AX7203") names no product, and preflight refusing it is the PRODUCT GATE working exactly as the header describes. That leaves one false red: 33204015910, a bare `workflow_dispatch`. On a dispatch `github.event.release.tag_name` is empty, so preflight's product gate takes its `*)` branch, prints "Tag '' names no product" and exits 1; every publishing job `needs: preflight` and is skipped. The dispatch cannot publish and cannot measure anything. It can only fail. The comment justifying it argued from `paths:` filters -- a gate nothing has matched in months is unmeasured rather than passing. This file has no `paths:` filter, so the argument was never about it. Removed, not repaired. Making a dispatch useful means giving preflight a tag input, which makes preflight SUCCEED on a dispatch -- and preflight refusing is currently the structural reason a dispatch cannot reach a registry. That trades a structural guard for five `if:` conditions standing in front of `cargo publish` and `npm publish` against live registries where a version is permanent, on a pipeline that has already burned golden-float 0.1.0 and golden-float-ffi 0.1.0. Not a trade worth making to remove one red run. The removal is commented in place, including why `tri gates unmeasured` will now advise adding a dispatch back and why that advice does not apply here.
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-06 04:43:51 UTC
Summary
Seal Status
|
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-06 04:51:59 UTC
Summary
Seal Status
|
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-06 05:00:47 UTC
Summary
Seal Status
|
`gates unmeasured` printed `dispatch: NO` for every workflow without a `workflow_dispatch:`, beside a footnote saying to add one. It could not tell a workflow that is missing a dispatch from one that refused a dispatch on purpose. #3325 removed the dispatch from `release.yml` -- every job keys off the release tag, which is empty on a dispatch, so preflight refuses and nothing publishes -- and recorded the reason in a YAML comment this tool does not read. The tool went on advising the next reader to put that dispatch back, in front of `cargo publish` and `npm publish` against live registries. Measured on #3325's head before this change: `2026-08-28 NO - Release Pipeline`. `has_dispatch` now returns three states instead of a bool, because the domain has three. A workflow records a deliberate refusal with `# tri:no-dispatch`, which is where the tool looks; `release.yml` now carries it. A present dispatch still wins over the marker, so a stale comment cannot hide a real one. Two of the six tests ask the wiring rather than the reader: the defect lived in a print site and a footnote, not in the predicate. The footnote test failed first, on a footnote I had silently failed to patch -- the python replace was a no-op and I had asserted only that the anchor existed, not that anything moved. CENSUS: `fetches` moved, `gates.rs:3596 fn unmeasured` -> `gates.rs:3651`. The function did not change; the three-state enum and its doc comment were added above it. `quiet` and `shell` did not move. Re-blessed in this commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* skill: spool five lessons from pass 119 (Refs #3236) Written with `tri skill add` and left UNNUMBERED, deliberately. A branch that also runs `fold` picks its number against its own base and collides exactly like a direct append; folding belongs after the merge. The five: - A refusal recorded only in prose is invisible to the tool that advises against it. `gates unmeasured` printed `dispatch: NO` beside "add `workflow_dispatch:` first" for the workflow #3325 had just deliberately removed one from -- that is, it advised putting a dispatch back in front of `cargo publish` on a live registry. A two-state predicate over a three-state domain is the shape. - Two date fields render in two timezones. `%ad` and `%cd` each print in their OWN recorded offset, which made one commit read as a seven-hour clock skew. Compared as epochs: 0 of 20. The tell was that the date order ran against topology. - Assert that the edit moved, not that the anchor exists. Two scripted edits reported success and changed nothing; the second because `find()` returned -1, `s[-1:j]` is the empty string, and `replace("", new)` inserts at position 0. - A private target dir hides the binary from the hooks. `.githooks/pre-commit:52` probes `$ROOT/target/{debug,release}/tri`; with `CARGO_TARGET_DIR` elsewhere the commit silently does not form while the next push reports success. - A gate whose workflow is not a required context cannot block a merge. This one refutes a claim I had already published in #3332: replayed over twelve first-parent commits with the tool unchanged, exactly one fails, blessed nineteen minutes later. `tri skill check`: 556 sections, no number used twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * skill: a quoted diagnostic is not a command invocation (Refs #3236) `Documented t27c subcommands exist` went red on this branch alone: dead `tri` mentions rose 141 -> 142. The offender was mine, and it was a QUOTATION. The lesson about stale binaries quoted the hook's own warning inside one code span -- `target/debug/tri is older than cli/tri/src`. The gate extracts `tri <word>` from code spans, so it read a subcommand `is`, which resolves on none of the four surfaces. Correctly: the gate is right, the text was wrong. Split into two spans, so the prose reads the same and the code spans name only paths: `target/debug/tri` is older than `cli/tri/src`. Measured rather than assumed, with both controls run first because the obvious probe was itself broken -- `$B $sub --help` does not word-split in zsh, so both mentions reported DEAD until the probe used `${=sub}`. With a must-resolve and a must-not-resolve control behaving correctly, the two `tri` mentions my files introduce (`tri census pin`, `tri gates unmeasured`) both resolve, and `tri is` is gone. The ratchet returns to 141. Not amended: the branch is pushed, and this repository never force-pushes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: lab <lab@example.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* fix(tri): a refused dispatch is not a missing one (Refs #3355) `gates unmeasured` printed `dispatch: NO` for every workflow without a `workflow_dispatch:`, beside a footnote saying to add one. It could not tell a workflow that is missing a dispatch from one that refused a dispatch on purpose. #3325 removed the dispatch from `release.yml` -- every job keys off the release tag, which is empty on a dispatch, so preflight refuses and nothing publishes -- and recorded the reason in a YAML comment this tool does not read. The tool went on advising the next reader to put that dispatch back, in front of `cargo publish` and `npm publish` against live registries. Measured on #3325's head before this change: `2026-08-28 NO - Release Pipeline`. `has_dispatch` now returns three states instead of a bool, because the domain has three. A workflow records a deliberate refusal with `# tri:no-dispatch`, which is where the tool looks; `release.yml` now carries it. A present dispatch still wins over the marker, so a stale comment cannot hide a real one. Two of the six tests ask the wiring rather than the reader: the defect lived in a print site and a footnote, not in the predicate. The footnote test failed first, on a footnote I had silently failed to patch -- the python replace was a no-op and I had asserted only that the anchor existed, not that anything moved. CENSUS: `fetches` moved, `gates.rs:3596 fn unmeasured` -> `gates.rs:3651`. The function did not change; the three-state enum and its doc comment were added above it. `quiet` and `shell` did not move. Re-blessed in this commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(now): a refused dispatch is not a missing one (Refs #3355) The NOW entry for the change in the previous commit. The pre-push gate refused the range without one, which is the gate paying for itself: that refusal cost a second here instead of a CI round. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: lab <lab@example.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Refs #3316
First, a correction to the triage.
release.ymlwas on the never-green listand should not have been — run
33180327861
succeeded on 2026-08-28, publishing
t27c 0.2.0. And of the two recentfailures,
33230021436is areleasewhose tag ("FPGA bitstreams — 43syntheses, AX7203") names no product; preflight refusing it is the PRODUCT GATE
working as the file's own header describes.
That leaves exactly one false red:
33204015910, a bareworkflow_dispatch.Why a dispatch here can only fail
On a dispatch
github.event.release.tag_nameis empty, so preflight's productgate takes its
*)branch:Every publishing job
needs: preflight, so all are skipped. The dispatch cannotpublish, and it cannot measure anything either. The comment justifying it argued
from
paths:filters — a gate nothing has matched in months is unmeasured ratherthan passing — but this file has no
paths:filter, so that argument was neverabout it.
Removed, not repaired
Making a dispatch useful means giving preflight a tag input — which makes
preflight succeed on a dispatch. Preflight refusing is currently the
structural reason a dispatch cannot reach a registry. Adding an input trades
that for five
if:conditions standing in front ofcargo publishandnpm publishagainst live registries, where a version is permanent, on apipeline that has already burned
golden-float 0.1.0andgolden-float-ffi 0.1.0. Not a trade worth making to remove one red run.The reasoning is left in the file, including why
tri gates unmeasuredwill nowlist this workflow as
dispatch: -and advise adding one back — for a pipelinekeyed on a tag there is no default-branch reading to take, which is the same
point the tool's own footnote makes about
pr-only.No job, step, or publish path is changed. Only the trigger.