fix(ci): the registry canary's triage guidance names the plugin-failed-to-load class - #16794
Conversation
…nd says a fix on main does not clear it The canary's triage template offered a closed binary — build failed, or a probe failed — and the failure it actually reported fit neither: AuthPlugin never loaded at boot because @better-auth/core@1.7.3 deleted the export plugin-auth statically imports, and the probe failures were a consequence. The template therefore routed the reader to the probes, away from the range. Add the boot-log branch, order it first (a failed probe is usually a consequence), and name the local reproducer. Also state the property that misled this round's triage: this job installs PUBLISHED artifacts, so a fix merged to main does not clear it — only a release does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
check:pnpm-acquisition reads a bare `pnpm <cmd>` token anywhere in a `run:` body as an invocation, so naming the reproducer that way put registry-canary — a job that acquires no pnpm and needs none — into the population of jobs that run pnpm (census 31, one failing). The underlying script needs no package manager and is what a reader can paste, so name it directly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
…g can discover Naming the reproducer as `node scripts/check-vendor-export-contract.mjs --resolve` traded one false positive for another: dispatch-gates discovers gate families from command-shaped text in `run:` bodies, so the prose became a discovered family inside registry-canary — a job in a workflow that declares no PR-time event. check:pm-dispatch-gates went red on its scheduled-only invariant (4 of 1552 cases), correctly. Any command-shaped text in a workflow `run:` body is read as a real invocation by at least two gates, so point at the workflow that runs the check instead of spelling a command inside guidance prose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
…tter-auth-core-range
Accepted by the Gate ① — CI35 raw check runs → 25 after latest-per-name collapse: 0 red, 0 pending,
⭐ The trap in that shape: the failing sentence was Gate ② — clause ②Both declaration documents read independently (⛔ not via the gate's 「both carriers agree」 sentence, which is about the label carriers — #16770):
They agree. The diff is one line of guidance prose in a workflow — no accept set relaxed, no published surface widened. The deviation from dispatch — checked, and it holdsThe dispatch asked for a changeset; this PR ships ⇒ nothing published moves when only ⭐ The premise change — and this seat's own error
And the half that is not fixed, read from the npm registry with a control:
⇒ Criterion 4 stays ⛔ NOT MEASUREDThe boot-warning count drop needs a canary run, and the canary installs published artifacts — so it is only readable after a release. ⭐ The delivery declined to claim it. ⭐ Two false positives worth keepingBoth gates behaved correctly, and the shape is not obvious: command-shaped prose inside a workflow Separately filed#16793 — publish-smoke's log scan runs after the probes and matches only Landing: marked ready and routed to the merge queue. ⛔ Not merged outside the queue; ⛔ no governed surface in this diff. ⛔ Card #16500 stays open on the release. Generated by Claude Code |
Part of #16500
⛔ Deliberately
Part of, notFixes. #16500 has to stay open on merge, because the published on-ramp is still broken for every new user and stays broken until a release ships. This PR delivers acceptance criterion 3 only. The half left open on that card is the release —@objectstack/plugin-auth@17.3.0is still thelatesttag and still declares"@better-auth/core": "^1.7.2", and cutting a release is the maintainer's by hand (Prime Directive #15).What this PR changes — and what it deliberately does not
⭐ The dependency-range half of this card was already fixed on
mainbefore it was dispatched. PR #16634 (2e6a2ea4c9, 2026-09-07 22:42 UTC) pinned the whole better-auth family to an exact1.7.2and addedcheck:vendor-export-contractplus its--resolvenetwork leg — the gate that answers criterion 2. The canary run this card was opened from (34084559243) fired at 04:47 UTC the same Monday, about 18 hours before that fix landed, and triage read the run log rather than the tree.So acceptance criteria 1 and 2 are already satisfied in source — measured below rather than assumed. This PR delivers criterion 3: the canary's own failure guidance, whose closed binary fit the real failure neither way and therefore routed the reader to the probes.
@objectstack/plugin-auth@17.3.0carries thelatesttag and still declares"@better-auth/core": "^1.7.2". This job installs PUBLISHED artifacts, so it stays red until a release ships — Prime Directive #15 territory, the maintainer's by hand. That is the one open action on this card.The change
One file, one line: the body the
registry-canaryjob files when it fails.failed to loadWARN in the boot log means a dependency-range problem, and it is the first thing to check whenever a probe fails, because the probe failure is a consequence. Carries the real specimen, and asks the reader to establish REMOVAL vs RENAME, which criterion 1 calls out as having different fixes.maindoes not clear this job; only a release does.Server is readyand the plugin count print on a degraded boot too ([finding] the server prints✓ Server is readyon a degraded boot — the ready signal is independent of the degraded-capabilities warning, and the louder one is wrong #16630), so neither narrows the branches. This cites that card, it does not fix it.Criterion 1 — reproduced and located, REMOVAL not rename
packages/plugins/plugin-auth/package.jsonis the only in-repo manifest naming better-auth (PM assumption 1 — confirmed, and extended past one level: the installed transitive graph showsbetter-auth@1.7.2declaring all seven of its own siblings exactly, so nothing downstream of it re-admits a float;pnpm-workspace.yamlcarries the same exact target for all eleven overridden members).Removal, not rename, measured against the registry rather than inferred:
No successor name exists in 1.7.3, so there is nothing to adapt to. Upstream rolled issuer-scoped account identity back to opt-in (better-auth/better-auth#10909).
Criterion 2 — how this does not recur, proved by ablation
The recurrence answer is the exact pin plus
check:vendor-export-contract-resolve, which validate-deps.yml runs on every manifest PR and daily at 03:00 UTC. Green on the tree as it stands:Ablation — restore the caret that shipped the break and confirm the gate goes red. Committed state, on-disk mutation proven by anchor counts and blob hash, trap-restored:
The resolve leg reproduces the canary's root cause verbatim, from the range alone, with no install of ours involved. That is the mechanism by which the class cannot recur silently.
Criterion 4 — negative control, and what it can and cannot say
Measured: the cause is gone in source. The declared range now admits exactly one version, and that version exports both symbols (gate above), so
AuthPlugin failed to loadcannot arise from this range for a consumer resolving it.⛔ Not claimed: the 4-to-N warning-count drop. That reading needs a canary run, and the canary installs published artifacts — so it can only be taken after a release. Reporting it as done here would be exactly the "the job went green" reasoning criterion 4 warns against. It is NOT MEASURED, and the reason is a release, not a gap in this PR.
Criterion 5 — #16630 and #16693 untouched
Neither is fixed here. Their causes both disappear once auth loads: the degraded-boot banner in #16630 had auth missing as its input, and #16693's ADR-0087 conversion warning fires on the scaffolded project independently. Their reporting is unchanged by this PR, which is the distinction the criterion asks for.
Two false positives this diff walked into — both real gates, behaving correctly
Worth recording, because the shape is not obvious: command-shaped text inside a workflow
run:body is read as a real invocation by at least two gates, even when it is prose inside aprintfthat files an issue.pnpm ...run putregistry-canaryintocheck:pnpm-acquisition's population of jobs that run pnpm — a job that acquires none and needs none. Census moved 31 jobs to 30 when the token left.node scripts/check-....mjs --resolveinstead made it a discovered gate family fordispatch-gates, inside a workflow that declares no PR-time event.check:pm-dispatch-gateswent red on its scheduled-only invariant, 4 of 1552 cases.Both are the gates working as designed. The guidance now points at the workflow that runs the check rather than spelling any command.
Verification
Gates derived from the delivered diff, reconciled, at
d917c083b9(after the merge oforigin/main, noSTALE TREEbanner):pnpm lint: the changed file matches no eslint configuration (--format jsonreports 1 entry, 0 errors, warning "File ignored because no matching configuration was supplied"). eslint's governed population therefore excludes.ymlentirely, and no type-aware linting is in play, so this diff cannot move a verdict on any untouched file. The narrowing is a measurement, not a skip.printfrender verified by executing the edited line with a stubrun_url— exit 0, body renders as intended, andcheck:nul-bytesplus a direct control-character scan are clean.No changeset —
skip-changesetThe diff touches
.github/workflows/publish-smoke.ymlonly. Measured: 0 of 82 package manifests list.githubinfiles[], so nothing published moves. The label is applied on this PR.Clause-②: no— re-declared from the delivered diff. The change adds no lenient alias, no??fallback and no relaxation of any consumer; it is guidance prose in a workflow.验收备注
Triage's acceptance criteria, verbatim:
^引入了@better-auth/core,以及它是在哪个版本移除了createLocalAccountIssuer。⛔ 不要直接改代码去适配新导出 —— 先确认这是移除还是改名,两者的修法不同。^范围。⇒ PR 要回答是收窄范围、加 peer 约束,还是别的。⛔ 只把当前这次修好,等于把 canary 变成一个每隔几周响一次的闹钟。AuthPlugin failed to load消失且 boot diagnostics 的告警数从 4 降下来。⛔ 不要只看作业变绿。✓ Server is readyon a degraded boot — the ready signal is independent of the degraded-capabilities warning, and the louder one is wrong #16630 或 ADR-0087'sfield-required-notnull-explicitconversion asserts an implication ADR-0113 abolished — the boot calls it a forward conversion, but its output and the source it prescribes disagree at the storage layer #16693。Out of scope, noted:
scripts/publish-smoke.sh, outside this card's declared file surface, and the fix is a new assertion rather than a mechanical edit.check:pnpm-acquisitionanddispatch-gatesboth read prose in arun:body as an invocation. Both give actionable messages and are conservative by design; the workaround is better guidance anyway.🤖 Generated with Claude Code
https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
Generated by Claude Code
Generated by Claude Code