Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .changeset/plugins-test-typecheck-onboarding.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
---
"@objectstack/embedder-openai": patch
"@objectstack/knowledge-memory": patch
"@objectstack/knowledge-ragflow": patch
"@objectstack/plugin-approvals": patch
"@objectstack/plugin-audit": patch
"@objectstack/plugin-auth": patch
"@objectstack/plugin-dev": patch
"@objectstack/plugin-email": patch
"@objectstack/plugin-hono-server": patch
"@objectstack/plugin-pinyin-search": patch
"@objectstack/plugin-reports": patch
"@objectstack/plugin-security": patch
"@objectstack/plugin-sharing": patch
"@objectstack/plugin-webhooks": patch
---

feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)

Every plugin package now has a `tsconfig.test.json` compiled by the shared
`check:test-typecheck` gate, and its `typecheck` script names it. Before this,
the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
(`plugin-security`, wired directly to `tsc` rather than to the instrument), and
0 `check:test-typecheck` scripts.

Onboarded as a family by the director ruling of 2026-09-01 on #14062
(maintainer verbatim: 「同意」), which also carries the #5286 maintainer
authority the starting ledgers need. The smaller branch triage recommended —
declare the instrument's scope and re-site the two compile-time pins — was
recorded as considered and not taken: an instrument silent over a third of the
runtime surface is a hole readers generalise across, and that costs more than
fourteen tsconfigs.

**Measured, not assumed** (at `e80889095`, workspace closure built first). Four
packages carry residue and therefore a starting ledger — plugin-approvals 324
over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
any error there is red immediately with no entry to be added to — strictly
stronger than a ledger holding nothing, and the call `plugin-security` had
already recorded for itself.

⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
ratchet able to *see* them; paydown follows the ratchet's own shrink-only
discipline on its own cards. No test file is edited here.

Two corrections to the finding's own prose, both measured: the exclusion is
narrower than "no plugin package compiles its tests" — 9 of the 14 already
compiled their tests inside the `typecheck`-invoked build config, at zero
errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
`**/*.test.ts` never excluded, so its directives were already live. The pin
this change genuinely makes real is
`plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
program had ever read.
4 changes: 3 additions & 1 deletion packages/plugins/embedder-openai/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,13 +16,15 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/embedder-openai --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/spec": "workspace:*"
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/embedder-openai/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 371
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4 changes: 3 additions & 1 deletion packages/plugins/knowledge-memory/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,8 @@
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-memory --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -25,6 +26,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
70 changes: 70 additions & 0 deletions packages/plugins/knowledge-memory/tsconfig.test.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
// The TEST-layer type-check program (#14062 — the `packages/plugins/**` family
// adopting the mechanism #5286 set for `packages/spec`, #5449 generalised,
// #12542 carried to `packages/rest` and #13176 to `packages/plugins/
// plugin-security`). `tsconfig.json` beside this one stays exactly as it is: it
// is the BUILD config. This sibling puts the test layer in front of tsc under
// the module semantics vitest really executes it with, and `package.json`'s
// `typecheck` script NAMES it (via `check:test-typecheck --project`), because a
// config no script invokes is exactly the phantom this whole change is about.
//
// The family was onboarded as a family by the director ruling of 2026-09-01 on
// #14062 (maintainer verbatim: 「同意」), which also carries the #5286
// maintainer authority for the starting ledgers. The reason it is a family and
// not one package: the ledger's shrink-only guarantee said NOTHING about a
// third of the repo's runtime surface, and a guarantee with a silent hole is
// worse than a narrower one honestly drawn, because readers generalise it.
//
// What differs from the build config, and what deliberately does NOT:
// - MODULE SEMANTICS ONLY, plus `lib`. The tests are written and executed as
// ESM by vitest (esbuild/vite). Matching that is FIDELITY, not laxity: it is the
// same subtraction `packages/spec`, `packages/rest` and `plugin-security`
// each made, and it removes a config-tier error pile that says nothing
// about the tests.
// - ⛔ STRICTNESS IS UNTOUCHED. `strict`, `noUnusedLocals`,
// `noUnusedParameters`, `noImplicitReturns`, `noFallthroughCasesInSwitch`,
// `rootDir`, `paths` and `types` are all INHERITED from `tsconfig.json`
// (and through it the root config), and none of them is re-declared here.
// ⚠️ A child that declared its own `paths` would REPLACE the parent map
// rather than merge into it, silently sending a source-resolved specifier
// back to `dist/` — a BUILD ARTIFACT — so this file declares none.
// Nothing here may loosen a type rule; if a test does not compile, that is
// the finding.
//
// - `lib: ["ES2022"]`, for the same reason `packages/rest` states: the root
// config's `lib` is ES2020 and vitest runs on a Node that has es2022
// builtins, so the gap is reported as TS2550 about the CHECK. No `DOM`:
// nothing in this layer touches a browser global.
//
// MEASURED at e80889095, workspace closure built first (`tsc --noEmit --pretty false
// --listFiles -p tsconfig.test.json`, and the same command without `--listFiles`):
//
// files in this program 388
// own `src/**/*.test.ts` in it 1
// errors under BUILD semantics 0
// errors under THIS config 0
//
// The two readings agree, so this package carried no config-tier pile at all.
//
// BEFORE THIS FILE: the build config does NOT exclude tests, so `tsc
// --noEmit` already read this one file. This program is the family's
// uniform instrument over the same file, not a new reader of it.
//
// There is NO `test-typecheck-debt.json` beside this config, and its ABSENCE is the
// zero: `check:test-typecheck` reads a missing ledger as `{ entries: {} }`, under which
// ANY error in ANY file here is red immediately, with no entry to be added to. That is
// strictly stronger than a ledger holding nothing, and it is the same call
// `plugin-security` recorded for itself in #13176. If this package ever acquires
// residue that cannot be fixed in the PR that causes it, THAT is when a ledger and a
// `gen:test-typecheck-debt` script are owed — and adding one is maintainer-only
// (#5286), exactly as the gate says when it refuses.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2022"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
6 changes: 5 additions & 1 deletion packages/plugins/knowledge-ragflow/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,10 @@
"scripts": {
"build": "tsup --config ../../../tsup.config.ts && node ../../../scripts/check-dts-emitted.mjs",
"dev": "tsc -w",
"test": "vitest run"
"test": "vitest run",
"typecheck": "tsc --noEmit && pnpm check:test-typecheck",
"check:test-typecheck": "tsx ../../../scripts/check-test-typecheck.mts --self-test && tsx ../../../scripts/check-test-typecheck.mts --package packages/plugins/knowledge-ragflow --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/knowledge-ragflow --project tsconfig.test.json"
},
"dependencies": {
"@objectstack/core": "workspace:*",
Expand All@@ -24,6 +27,7 @@
},
"devDependencies": {
"@types/node": "^26.2.0",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/plugins/knowledge-ragflow/test-typecheck-debt.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"_comment": "Per-file tsc error debt of the @objectstack/knowledge-ragflow TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed. THIS FIELD IS GENERATED: every regeneration rewrites it from scripts/check-test-typecheck.mts, and the EXACT ratchet below requires a regeneration on every repair — so an edit made here is gone by the next one. Anything true of THIS package goes in the sibling `_note` field, which is authored, is preserved verbatim, and is never written by the generator (#12624). This comment states NO cause for the errors, deliberately: the classes differ per package and per file, they move as the debt is paid down, and a cause written here is rewritten verbatim into every ledger by every regeneration — so it outlives its own repair and cannot be corrected in the file where it is read. Measure instead, before repairing anything: `tsc --noEmit --pretty false -p tsconfig.test.json` in the package prints the real classes with their TS codes. Each entry maps a file to its per-SIGNATURE error counts, never to a bare total (#13470): a signature is the TS code plus the diagnostic message with structural type blobs collapsed, and it carries NO line or column — so the pin survives edits that move code around, and only stops matching when the error itself becomes a different error. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, a signature that ARRIVES or VANISHES is red even when the file total is unchanged, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/knowledge-ragflow gen:test-typecheck-debt",
"_note": "STARTING LEDGER, opened by #14062 under the director ruling of 2026-09-01 (maintainer verbatim: 「同意」), which carries the #5286 maintainer authority for it. 3 errors in 1 file, all PRE-EXISTING — and this package was silent for a DIFFERENT reason than its siblings: its `tsconfig.json` never excluded tests, so a tsc program would have read them, but the package declared NO `typecheck` script at all, and `turbo run typecheck` cannot run a script that does not exist. #14062 added one naming this gate. ⛔ That is not the repo-wide 'packages missing a `typecheck` script' carry-over, which the same ruling holds separate (item 5): this is the one invocation path #14062's own instrument needs in order to run here at all.",
"entries": {
"src/__tests__/ragflow-adapter.test.ts": {
"TS2353: Object literal may only specify known properties, and 'options' does not exist in type '…'.": 3
}
}
}
21 changes: 20 additions & 1 deletion packages/plugins/knowledge-ragflow/tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,24 @@
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
// [#14062] `**/*.test.ts` moved OUT of this program and INTO the sibling
// `tsconfig.test.json`, which `typecheck` names via `check:test-typecheck`.
// Read the direction carefully — this is not a package hiding its tests:
//
// This package declared NO `typecheck` script at all until #14062, so the
// fact that its tests were inside the BUILD program bought nothing; no tsc
// program was ever RUN over them, and the 3 errors they carry sat there
// unseen. Adding the script is what makes the program real, and it must
// invoke tsc (`check:type-check-coverage` refuses a `typecheck` that never
// type-checks). With the tests still here, that first limb would be red on
// arrival at debt this card is explicitly NOT chartered to repair — the
// ruling of 2026-09-01 says the job is to let the ratchet SEE the errors, and
// that repair follows the ratchet's own shrink-only discipline afterwards.
//
// So the split is the family's shape, not an exemption: `tsc --noEmit` here
// judges the shipped source, and every test file is judged one command later
// by `check:test-typecheck` against an EXACT, shrink-only per-signature
// ledger. Nothing stops being compiled; the two halves are named separately
// so each can be true about its own layer.
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading