Uh oh!
There was an error while loading. Please reload this page.
fix(plugin-sharing): require warn on the orphan sweep logger and pin every required warn - #12275
Conversation
…n every required warn (#10692) Part of #10692 — the ruled remainder (option A, maintainer 2026-08-25) after PR #11856 landed the three publicly exported producers under #10556 limb (c). - record-orphan-cleanup.ts's module-local MinimalLogger drops its bare Function members for the producers' real signatures and makes warn REQUIRED: every report the sweep emits lands on warn, so a logger without a guaranteed warn is one the sweep loses its only output into (#9754's permit-silence shape, one module downstream of the tightened producers). Zero in-repo call-site cost: both callers forward the owning services' logger options, whose warn is already required. - logger-required-warn.pin.ts pins the contract at compile time for all four sinks (three public options types + the sweep parameter): a { info, error }-only literal is refused, a bare { warn } stub stays legal, and a value of type Function no longer satisfies the members. Pins live in a src-level .pin.ts because this package's tsconfig excludes tests from tsc; the file deliberately declares no type literals with channel members so check:optional-error-sink's census never reads it. - logger-shapes.ts's shape map is updated: the record-orphan-cleanup row no longer describes bare Function as blocked, and names the pin file. - Changeset: minor with the published-contract break declared (BREAKING) and the one-line host fix named, per the launch-window convention. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UQgPSniH1GFM9ZDeGyuGUa
📓 Docs Drift Check5 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. What this run could not see
Coarse fallback — 8 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 4ca01b2b7108c62f149765d33058995dec27cabd && git checkout 4ca01b2b7108c62f149765d33058995dec27cabd
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f86839d4cd5543a0f8c7a3f4806b0d0b35a33524 9abad39a115a3a608b173d869a93ae316bbc97bf && git checkout -B drift-repro f86839d4cd5543a0f8c7a3f4806b0d0b35a33524 && git merge --no-ff 9abad39a115a3a608b173d869a93ae316bbc97bf
node scripts/docs-audit/affected-docs.mjs --json f86839d4cd5543a0f8c7a3f4806b0d0b35a33524 |
os-trump
commented
Aug 25, 2026
Contract-review verdict: PASS (#10692)Reviewed by the contract-review chain at Reviewed: the full diff (all 4 files), the changeset, and the ruling record on #10692. Conformance to ruling A (maintainer 2026-08-25, 「同意」 — real signatures, required
One named gap, recorded rather than blocking: the ruling's out-of-repo sweep measured objectui (zero hits at the pinned ref) but Landing completed by the chain in the same stroke per the maintainer's standing instruction (2026-08-25, verbatim: 「审核通过你应该直接负责合并吧,还要等原始的项目经理吗」): clearing Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#10692
What this PR does — the ruled remainder of option A
The maintainer ruled option A on this card (2026-08-25): real signatures and a required
warnon this package's logger sinks, with thecheck:optional-error-sinkbaseline rows paid down rather than made permanent. The producer half — the three publicly exported options typesSharingServiceOptions,ShareLinkServiceOptions,SharingRuleServiceOptions— already landed on 2026-08-24 in PR #11856 under #10556 limb (c), together with the deletion of the three plugin-sharing baseline rows (the ledger is now 1 row, the recorded deliberate exception). This PR delivers what remained on this card:record-orphan-cleanup.ts— the module-localMinimalLoggerdrops{ info?: Function, warn?: Function }for the producers' real signatures ((msg: any, ...rest: any[]) => void) with a requiredwarn. Every report the sweep emits lands onwarn(the "could not check", "stopped early" and "revoked N rows" lines), so a warn-less logger is one the sweep loses its only output into — A sink type declaring an optionalerrorwith no declared alternative is a contract that permits silence — require a fallback channel #9754's permit-silence shape, one module downstream of the producers Pay down the optional-error sink ledger — 13 paid, 2 remain and both are DESIGN CALLS (was: "15 sink types") #10556 tightened. In-repo call-site cost: zero — both callers forward the owning services'loggeroptions, whosewarnis already required.logger-required-warn.pin.ts(new, src-level) — compile-time pins for all four sinks (the three public options types and the sweep's logger parameter): a{ info, error }-only literal is refused, a bare{ warn }stub stays legal (positive control), and a value of typeFunctionno longer satisfies the members. A src-level.pin.tsbecause this package's tsconfig excludes tests from the tsc program a pin needs; the file deliberately declares no type literals carrying channel members, so the sink census never reads it.logger-shapes.ts— the shape-map docblock's record-orphan-cleanup row no longer describes bareFunctionas blocked, and names the pin file.minorwith the published-contract break declared (BREAKING) and the one-line host fix named (add awarncallback, or omit the optionalloggerargument), per the launch-window convention and the refactor(plugin-auth): remove the inert AUTH_SCIM_PROVIDER_SCHEMA export (enforce-or-remove) #12008 precedent. ADR-0087 disposition:not-required (no-migration-prescription), accepted by the gate.Dispatch-brief premise, re-verified against origin/main
The brief (2026-08-25 14:51Z) said the three public sinks were "currently baselined" and included the producer tightening in this card's surface. That was stale on arrival: PR #11856 (merged 2026-08-24 22:01Z) had already tightened all three producers and deleted their baseline rows. Verified byte-level on the base commit before any edit; nothing of #11856's work is redone here. The record-orphan-cleanup consumer, the pins, the sibling sweep and the changeset were the live remainder.
The load-bearing gate, run by hand on both sides
pnpm check:optional-error-sink, exit codes captured before any pipe, quoting the gate's own lines.BEFORE (base
cd2541780, exit 0):AFTER (this PR's head
9abad39a1, exit 0): byte-identical population line and verdict line (diff of the two full outputs is empty), and the informational "99 pure sink(s) declare noerror" tally is also unchanged — predicted in writing before editing: the sweep's sink declares noerrormember on either side of this change, so it never enters the population, and the pin file is invisible to the census by construction. The dispatch-measured trap (population 37 to 39, gate turning red) belonged to the pre-#11549/pre-#11856 tree; on today's tree the predicted movement was zero, and zero was observed.Ablations — direction predicted in writing first, restored to HEAD
Fix committed first; each leg is a script with an
EXIT INT TERMtrap restore, an anchor asserted to occur exactly once before editing, and the mutation proven on disk by grepping the injected spelling (1) and the surviving old spelling (0). No build step exists in these legs to skip: the mutated file and the pins sit in one package compiled from source by a singletsc --noEmit, nothing resolves through dist.warnback to optional. Predicted: exactly 1 error, TS2578 unused-directive at the sweep refusal pin; bare-Function pin stays satisfied; exit 2. Observed: exactly that —logger-required-warn.pin.ts(72,3): error TS2578, 1 error, exit 2.SharingServiceOptionswarnback to optional. The original prediction (1 error) was amended in writing before running: with the sweep now requiringwarn, loosening the producer must also break the forwarding seam. Amended prediction: exactly 2 errors — TS2578 at the SharingSink refusal pin, plus TS2345 at sharing-service.ts's sweep call. Observed: exactly that —logger-required-warn.pin.ts(66,3): error TS2578andsharing-service.ts(1405,7): error TS2345, 2 errors, exit 2. The second error is the forwarding-seam diagnostic this type family exists to produce.Both restores verified:
git status --porcelainempty for the path andgit diff HEAD --statempty (disk == index == HEAD).Sibling-host sweep (the ruling's own dispatch instruction)
194fae184372ffe4c5719427d707a2900693fff2(fresh clone of the default branch): zero imports of@objectstack/plugin-sharing(grep exit 1 over ts/tsx/json), zero warn-less logger literals (every single-line brace span naming bothinfoanderroralso nameswarn; the only structural logger type found,packages/types/src/plugin-scope.ts:214, declares all three channels). Zero consumer cards to file.Verification (all at head
9abad39a1, exit codes captured before any pipe)pnpm --filter '@objectstack/plugin-sharing^...' build(dependency closure, via the shared verify lock): command-exit 0.pnpm typecheck(plugin-sharing, script line echoed once): exit 0, 0 errors.pnpm --filter @objectstack/plugin-sharing exec vitest run --maxWorkers=2: Test Files 27 passed (27), Tests 652 passed (652), exit 0.check:optional-error-sinkboth sides as quoted above.node scripts/pm/dispatch-gates.mjs, no paths passed — 13 named + 2 convention):check:changeset-gate-self-tests,check:objectui-changeset,check:published-files,check:slot-lookup,check:test-source-alias,check:type-source-resolution,check-adr-0087-registration(judged this changeset declared-breaking, marker accepted),check-changeset-no-major,check-empty-changeset,check-plugin-teardown-shape,docs-audit/check-affected-docs,release-rehearsal-clone --self-test,check:i18n(after building the CLI it requires),check:i18n-stale-fill, pluscheck:nul-bytes— all exit 0.Review status
Clause-② is yes per the dispatch: this PR carries
needs:contract-reviewand stays a draft — the contract-review chain flips it, not this seat.Generated by Claude Code