Defect
edtf v1.3.2's registry legs failed three consecutive times (run
32681747423 + two re-runs) and the cause is the canon's, not the
repository's. Measured 2026-08-24 by a claims probe on an edtf branch
(runs 32684527127, 32684570428, 32684599155 — branch oidc-probe,
deleted after):
- GitHub's OIDC mint is HTTP 200 with complete, correct claims
(repository monumental-archive/edtf, environment publish,
ID-stamped immutable sub) — the failure is registry-side.
publish-rust-crate.yml's exchange curl (line ~109) sends no
meaningful User-Agent, and crates.io's protection layer 403s it with
the data-access-policy boilerplate — a misleading, unattributed
refusal that reads like a trust mismatch. With a User-Agent naming
the org, the same exchange proceeds to real validation and answers
HTTP 400 naming the probe's wrong filename and listing the FIVE
configured publish.yml publishers — i.e. the repository's
trusted-publishing config is correct and complete, and the header is
the entire crates-side defect.
- The npm leg fails
ENEEDAUTH in the same runs. Boundary measured:
the mint works (above), release-lab published npm 2026-08-21 through
the identical workflow, and the package's trusted publisher was
re-verified during the failures. The one measured delta: edtf pins
node = "26.5.1", the lab pins 24.19.0 — the bundled npm differs,
and npm's OIDC trusted publishing is npm-version-sensitive. Unproven;
the build pins it by measurement.
Consequence recorded: v1.3.2's crates/npm legs are unreachable at that
tag forever (the tag's tree pins canon v1.60.0), so v1.3.2 is a partial
burn — GitHub release published with full evidence, registries not.
edtf's next release after the pin bump completes the arrival.
Decided build
Decided 2026-08-24, from the probe:
- the crates exchange curl gains
User-Agent: monumental-archive-publish (https://github.com/monumental-archive/.github)
— an org-identifying UA per crates.io's own data-access policy, with a
comment quoting the boilerplate 403 so the next reader recognises the
block if the policy tightens again.
- sweep every
curl in the publish/release workflows and release/
scripts that targets a third-party registry (crates.io, npmjs, zenodo)
for the same gap; GitHub-API curls keep their existing shape.
- the npm leg: measure
npm at node 26.5.1 vs 24.19.0 for OIDC trusted
publishing (the CLI's own debug log names the step); fix belt-side if
it is a canon assumption, or file the edtf pin correction if it is the
repo's node pin — whichever the measurement says. Do not ship a token
fallback: the workflow's deliberate ENEEDAUTH-over-weaker-auth stance
stays.
Rejected, recorded: emailing crates.io for an allowlist (the header is
the documented contract); retrying v1.3.2 (the tag's pin cannot see any
fix by construction).
Canon consequence
Release-path change: rides the next canon release, no lab leg (standing
ruling — and the lab could never have caught this: rust-crate is not in
the lab's class list, the paths-proven-only-by-real-repos family). Every
consumer's registry legs inherit the header at their pin bump.
Done when
Sequencing
Immediate — it blocks edtf's arrival on both registries. Canon release
after merge; edtf pin bump; edtf release next. Refs #833, #834,
release-lab#262 (proof ledger).
Defect
edtf v1.3.2's registry legs failed three consecutive times (run
32681747423 + two re-runs) and the cause is the canon's, not the
repository's. Measured 2026-08-24 by a claims probe on an edtf branch
(runs 32684527127, 32684570428, 32684599155 — branch
oidc-probe,deleted after):
(
repository monumental-archive/edtf,environment publish,ID-stamped immutable sub) — the failure is registry-side.
publish-rust-crate.yml's exchange curl (line ~109) sends nomeaningful User-Agent, and crates.io's protection layer 403s it with
the data-access-policy boilerplate — a misleading, unattributed
refusal that reads like a trust mismatch. With a User-Agent naming
the org, the same exchange proceeds to real validation and answers
HTTP 400 naming the probe's wrong filename and listing the FIVE
configured
publish.ymlpublishers — i.e. the repository'strusted-publishing config is correct and complete, and the header is
the entire crates-side defect.
ENEEDAUTHin the same runs. Boundary measured:the mint works (above), release-lab published npm 2026-08-21 through
the identical workflow, and the package's trusted publisher was
re-verified during the failures. The one measured delta: edtf pins
node = "26.5.1", the lab pins24.19.0— the bundled npm differs,and npm's OIDC trusted publishing is npm-version-sensitive. Unproven;
the build pins it by measurement.
Consequence recorded: v1.3.2's crates/npm legs are unreachable at that
tag forever (the tag's tree pins canon v1.60.0), so v1.3.2 is a partial
burn — GitHub release published with full evidence, registries not.
edtf's next release after the pin bump completes the arrival.
Decided build
Decided 2026-08-24, from the probe:
User-Agent: monumental-archive-publish (https://github.com/monumental-archive/.github)— an org-identifying UA per crates.io's own data-access policy, with a
comment quoting the boilerplate 403 so the next reader recognises the
block if the policy tightens again.
curlin the publish/release workflows andrelease/scripts that targets a third-party registry (crates.io, npmjs, zenodo)
for the same gap; GitHub-API curls keep their existing shape.
npmat node 26.5.1 vs 24.19.0 for OIDC trustedpublishing (the CLI's own debug log names the step); fix belt-side if
it is a canon assumption, or file the edtf pin correction if it is the
repo's node pin — whichever the measurement says. Do not ship a token
fallback: the workflow's deliberate ENEEDAUTH-over-weaker-auth stance
stays.
Rejected, recorded: emailing crates.io for an allowlist (the header is
the documented contract); retrying v1.3.2 (the tag's pin cannot see any
fix by construction).
Canon consequence
Release-path change: rides the next canon release, no lab leg (standing
ruling — and the lab could never have caught this: rust-crate is not in
the lab's class list, the paths-proven-only-by-real-repos family). Every
consumer's registry legs inherit the header at their pin bump.
Done when
boilerplate; org UA → 400/200 with real validation prose
— run linked here (this is also the rust-crate class declares a planned SBOM obligation with no producer: emit the plan and lint the declaration/producer join #833/batch 2026-08-21 status: where the import batch stopped and what picks up #834's completing evidence)
the failing step, and its fix landed wherever the measurement points
mise run cigreen on the commitSequencing
Immediate — it blocks edtf's arrival on both registries. Canon release
after merge; edtf pin bump; edtf release next. Refs #833, #834,
release-lab#262 (proof ledger).