Uh oh!
There was an error while loading. Please reload this page.
fix(plugin-approvals): require warn on ApprovalServiceOptions logger sink - #10937
Conversation
…sink Drops the `?` from `warn` on ApprovalServiceOptions['logger'] so a sink declaring an optional `error` always has a guaranteed durability-report channel (#9754, #10556). `error` stays optional. This is the thirteenth of the card's thirteen mechanical repairs -- held out of #10691 to serialize against PR #10547, which owned this file while open; that fence cleared when #10739 merged. Deletes the now-stale row from the shrink-only scripts/optional-error-sink-contract.baseline.json (the checker itself named the row as no-longer-red). The other two rows -- plugin-security's default-sink design call and service-settings' no-fallback design call -- are untouched; both remain escalated to the maintainer. No construction site needed a widening fix: the sole non-test call (ApprovalsServicePlugin.start) passes ctx.logger, whose warn is already required by the core Logger contract. Part of #10556. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0f14f70b-575c-5f2b-a235-4000a55db042
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32520389049 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Part of #10556
What
Drops the
?fromwarnonApprovalServiceOptions['logger']so a sinkdeclaring an optional
erroralways has a guaranteed durability-reportchannel (#9754).
errorstays optional. This is the last of the card'sthirteen mechanical repairs — held out of #10691 to serialize against
PR #10547, which owned
approval-service.tswhile it was open; that fencecleared when #10739 merged (2026-08-21T14:40Z).
Deletes the now-stale
logger@ApprovalServiceOptionsrow from theshrink-only
scripts/optional-error-sink-contract.baseline.json, identifiedby running
pnpm check:optional-error-sinkafter the type fix and using itsown "1 stale entry(ies)" verdict as the deletion criterion (not by line
number). The other two rows —
plugin-security's default-sink design calland
service-settings's no-fallback design call — are untouched; bothremain escalated to the maintainer per #10556's re-triage
(issuecomment-5368213444). Baselined count after this PR: 2 (as
expected).
⛔ Not
Fixes #10556— the card still carries two unruled designdecisions; a closing keyword would silently close their only tracking
artifact.
Construction-site re-check
The sole non-test construction site (
ApprovalsServicePlugin.start, samepackage) passes
ctx.logger(PluginContext['logger']), whoseLoggercontract already requires
warn— zero widening needed.pnpm --filter '@objectstack/plugin-approvals' typecheckis clean (echoedtsc --noEmitthen done — not a zero-match pass). Test-file loggers (
noopLogger,capturing, inline{ warn: ... }spies) already declarewarn; noneneeded a change.
Ablation (both directions, predicted before mutating)
with "no guaranteed fallback channel". Observed exactly:
✗ 1 sink type(s) declare an optionalerrorwith no guaranteed fallback channel ... sink: inline type logger@ApprovalServiceOptions { info? warn? error? debug? }. Restored viagit checkout HEAD -- packages/plugins/plugin-approvals/src/approval-service.ts(fix wasalready committed) —
git hash-objectconfirms byte-identical restore(
20083b9a4ab5ef6e3d3cff46bfcf12701d968df8).stale entry.Observed exactly:
✗ 1 stale entry(ies) in scripts/optional-error-sink-contract.baseline.json ... packages/plugins/plugin-approvals/src/approval-service.ts::logger@ApprovalServiceOptions— proves the row deletion is a required part of this fix, not tidying.
Restored via
git checkout HEAD -- scripts/optional-error-sink-contract.baseline.json,byte-identical (
1a933af08d6aa911b7377d63effc352c8116d80a).Tests
All at final head
1a9baa986, exit codes captured before any pipe.pnpm check:optional-error-sink: exit 0 —✓ optional-error sink contract: every sink declaring an optionalerrorguarantees awarnchannel (**2** baselined, shrink-only).pnpm --filter '@objectstack/plugin-approvals^...' build: exit 0 (dependencyclosure — upstream direction,
^...).pnpm --filter '@objectstack/plugin-approvals' typecheck: exit 0.pnpm --filter '@objectstack/plugin-approvals' test -- --maxWorkers=2: exit0 — 536 tests / 28 files passed.
pnpm check:route-envelope -- --self-testandpnpm check:dispatcher-error-vocabulary -- --self-test: both exit 0. Thegate-union derivation (
node scripts/pm/dispatch-gates.mjs, no path args)did not name either — this diff touches no
packages/plugins/plugin-auth/**path, so class [finding] Every PM dispatch list is short by the same ~5 changeset-triggered gate families — they are path-derivable, but the changeset does not exist yet when the list is derived #10309 does not apply to this PR's surface; run anyway per
dispatch item 7 and both green.
check:empty-changeset,check:adr-0087-registration,check:changeset-no-major(and the bundledcheck:changeset-gate-self-tests)all exit 0 on the committed tree.
check-adr-0087-registrationverdict:[BREAKING] not-required (runtime-interface-only) -- verified: packages/plugins/plugin-approvals/src/approval-service.ts#ApprovalServiceOptions (interface).node scripts/pm/dispatch-gates.mjs(no pathargs, run after the final commit, clean tree): all 15 path-matched
families green, plus the one convention-triggered gate (
pnpm check:i18n,triggered because this package owns an
i18n-extract.config.ts) greenafter building the CLI (
check:i18n's own prerequisite — it exits 1 with"PREREQUISITE NOT MET" and checks nothing until the CLI is built).
Bump / ADR-0087 reasoning (read #10691's changeset first, per dispatch)
minor, matching #10691's twelve sibling repairs:majoris banned bycheck-changeset-no-major.mjsduring the launch window (lockstepversioning), and
patchwould be wrong because this can break a consumer'sbuild (compile-time only, no runtime change). No exemption for a types-only
break was found, matching #10691's own search.
not-required (runtime-interface-only):ApprovalServiceOptionsis a plainTypeScript interface — no Zod projection, no metadata surface, not
referenced by one — so
objectstack migrate metahas nothing to rewrite.Nothing is removed or renamed (AGENTS.md's FROM→TO prescription requirement
is scoped to removal/rename) and no stored value moves.
⭐ Instrument note (confirmed again on this PR):
check-adr-0087-registrationreads changeset content from git, not theworking tree — it must be re-run after committing the changeset to carry
any information.
Generated by Claude Code