fix(service-settings): wire the typecheck script and clear the 14 errors the unexecuted gate hid - #7959
Merged
Conversation
…rrors the unexecuted gate hid (#7925) `turbo run typecheck --filter=@objectstack/service-settings` exited 0 while never running a typecheck task: the package declared only `build` and `test`, and turbo silently no-ops a package missing the script. Adding it (mirroring `service-messaging`) makes the task real — 7 tasks where there were 6 — and surfaced 14 pre-existing errors in five test files. All 14 are stale tests, not source defects; no non-test source file changed. The manifest action-handler tests called handlers with a partial input while `SettingsActionHandler` and every service call site pass `{ namespace, actionId, values, payload?, ctx }`; the audit-sink test returned `Array.push`'s number from a `void` callback; the translation-coverage guard narrowed the manifests barrel through a hand-rolled type that had drifted from the spec's `SettingsManifest`. Nothing was silenced: no `any` added, no `@ts-expect-error`, tsconfig `include` unchanged. The five `as any` casts already hiding the same drift in `ai.manifest.test.ts` are removed rather than copied, and the `aiTestEmbedderActionHandler` import the compiler flagged as unused is now exercised — the `test_embedder` action button had no coverage. `service-settings` graduates out of the `check:type-check-coverage` DEBT ledger: 63/77 -> 64/77 packages type-checked, 455 -> 442 frozen raw errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ALEcHx72USrxEFv8Z2fKt1
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
huangyiirene
marked this pull request as ready for review
August 12, 2026 09:30
This was referenced Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7925
The premise, re-measured on this branch's base (
6ff179d)Confirmed, exactly as filed:
packages/services/service-settings/package.jsondeclared onlybuildandtest.turbo run typecheck --filter=@objectstack/service-settingsexited 0 having run 6 tasks — all of them^builddependencies, never aservice-settings:typecheck. Turbo silently no-ops a package missing the script and reports success.tsc --noEmitin the package surfaced 14 errors across the five named test files. Note the package's tests live undersrc/, so the tsconfigincludealways reached them — only the script that runs the compiler was missing.After the one-line script (mirroring sibling
service-messaging), the same command runs 7 tasks, the new one being a realservice-settings:typecheck, and it is green.Per-error verdict — 14 of 14 are stale tests
No
service-settings/src/**non-test file changed. Every error was a test that had drifted from a contract that legitimately grew.manifests/sms.manifest.test.ts{ values, ctx }manifests/storage.manifest.test.tsmanifests/ai.manifest.test.tsaiTestEmbedderActionHandlerimported, never usedsettings-service.test.tsnumbernot assignable tovoid | Promise<void>translations/settings-translation-coverage.test.tsDetails:
SettingsActionHandlertakes{ namespace, actionId, values, payload?, ctx }, andsettings-service.ts:1809— the only invocation site — passes all of it. The tests still used the older two-field shape. They now call handlers the way the service does (namespace: 'sms' | 'storage',actionId: 'test', taken from each manifest's ownaction_buttonid).SettingsContextis all-optional, soctx: {}type-checks with no cast.ai.manifest.test.ts. Its five calls were alreadyas any— the same drift, pre-silenced. Those casts are removed, not extended to the other two files. The unused import was there becauseaiTestEmbedderActionHandlerwas never tested despite the manifest declaring atest_embedderbutton for it; rather than delete the import, its two branches (disabled provider, missing API key) are now covered. Net +2 tests.settings-service.test.ts:143.record: (e) => events.push(e)returnedArray.push's number from a sink declaredPromise<void> | void. Braced.settings-translation-coverage.test.ts. It filtered the manifests barrel through a hand-rolled structuralManifest/Specifierpair that had drifted from the real shape (labelisstring | Record<string, string>, notstring), so its type predicate was not assignable to the union it narrowed — TS2677, with four cascading errors downstream because an invalid predicate leavesfilterreturning the unnarrowed union. It now narrows to the spec's ownSettingsManifest; the local duplicates are deleted.Nothing was silenced. No
anyadded, no@ts-expect-error, no change to the tsconfiginclude, and five existingas anycasts removed.The sweep — and a correction to the card's framing
The card suggests sweeping for other packages missing the script, on the premise that the silent no-op is untracked everywhere. That premise is false, and worth stating plainly: the invariant is already gated.
scripts/check-type-check-coverage.mjs(check:type-check-coverage/check:type-check-debt, #4311) already enforces exactly this — every workspace package either declares atypecheckscript or carries a measured DEBT entry with an error count and a tracking issue, and the ledger is closed to new debt.service-settingswas in that ledger aterrors: 13, with a note naming the very errors this PR fixes ("TS2345 x7: manifest action handlers called withoutnamespace/actionId; TS2322"). So this was tracked debt being paid down, not an unknown hole.The sweep (
jqover all 78 workspacepackage.jsons) finds 13 remaining packages without the script, and they reconcile exactly with the ledger — 13 DEBT entries + 1 EXEMPT (@objectstack/console, a published artifact with no TS sources), where one DEBT entry is the workspace root rather than a package directory:@objectstack/core@objectstack/metadata@objectstack/spec-monorepo(workspace root)@objectstack/metadata-protocol@objectstack/service-storage@objectstack/cloud-connection@objectstack/observability@objectstack/service-knowledge@objectstack/service-analytics@objectstack/service-automation@objectstack/knowledge-ragflow@objectstack/hono@objectstack/service-cluster@objectstack/consoleScoping decision: wire none of them here. Triage on #7925 already fenced the sweep out of this card (routing the mechanical invariant to #7849), and the measurement agrees — these are not a handful of clean packages, they are 442 frozen raw errors of already-tracked debt, four of them over 50. Wiring any of them means paying its burn-down, since this PR must leave green everything it wires. The survey is the deliverable; the burn-down belongs to #4311's per-package cards.
Ratchets — moved down, none raised
Removing
service-settingsfrom the DEBT ledger is required, not optional: the gate fails with "declarestypecheckbut still has a DEBT entry — it graduated; delete its entry". After deletion:check:type-check-coverage: 63/77 → 64/77 packages type-checked; DEBT 14 → 13 entries; frozen raw errors 455 → 442. Self-test passes (23 semantic + 24 observation + 15 re-measure + 12 built-closure + 9 auto-lowering cases).check:type-check-debt(--re-measure, against a fully built workspace): OK — 35 ledger entries re-measured, 1975 raw tsc errors total, none above its recorded number. Nothing raised.check:query-options-erasure: holds — 67 unswept non-test sites in 17 files, none new; baseline key set verified against6ff179d.check:engine-double-contract: OK — 166 pinned, 133 DEBT, 2 exempt. No engine fake touched.vitest runin the package: 401 passed / 401, 19 files.One pre-existing finding the re-measure surfaced (not caused by this PR, not fixed here)
The
--re-measurepass reports 272 raw errors of surplus across 9 ledger entries sitting below their recorded ceiling — headroom in which regressions can land silently (#6376). None of them isservice-settings, and nothing in this diff moved any of them:metadata92→89 ·service-automation5→3 ·service-storage52→51 (DEBT);plugin-approvals547→348 ·plugin-auth131→108 ·mcp63→53 ·lint42→19 ·plugin-security21→11 ·http-conformance4→3 (TEST_DEBT).pnpm check:type-check-debt --lowerwould close all nine in one write, but that rewrites nine ledger entries across eight unrelated packages on a one-package card — exactly the ballooning this card's scope forbids. Reported rather than done; it belongs to #6376.#5536 ride-along: did not fire
The conditional trigger was
packages/services/service-settings/src/settings-service.ts:1200. Clearing all 14 errors required no edit tosettings-service.ts— the file is read-only in this work (its line 1809 is cited as evidence for the handler contract, nothing more). No single-point fix of storagehasAny; no promotion of #5536.Not done, deliberately
check:type-check-debt的 ledger 余量会让新写的 pin 变哑:mongodb 曾有 33 条余量吞掉一次真实回退,另有 5 条目前带 4–19 余量 #6376's business.