feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude
, '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

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet - #14916

Merged
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script
Sep 3, 2026
Merged

feat(tooling): @objectstack/core declares a typecheck script; test and examples layers enter the ratchet#14916
os-musk merged 3 commits into
mainfrom
claude/issue-14613-core-typecheck-script

Conversation

@os-musk

Copy link
Copy Markdown
Collaborator

Fixes#14613

@objectstack/core declared exactly build, test, test:watch. turbo run typecheck selects only packages that declare the task, so the lint workflow's typecheck job could not reach this package, and pnpm --filter @objectstack/core typecheck failed with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it — which is how a dispatched task came to assume it existed.

The card asked for the count before any repair. Here it is.

Measured at 84b8190ae, dependency closure built first

programfileserrors
tsc --noEmit -p tsconfig.json (undivided — exactly as the DEBT entry measured it)12 with errors98
the same program over only the non-test sources630
the 48 test files under vitest's own module semantics484

98 reproduces the ledger to the unit, and the class breakdown matches it line for line: TS7006 x71, TS2835 x22, and one each of TS6133, TS2739, TS2352, TS2347, TS18046. All 12 files are .test.ts.

So the build layer graduated as it stood, and 94 of the 98 were the CHECK, not the code.

What landed

The split this repo already runs for spec, rest, objectql and client:

  • tsconfig.json stays the BUILD config and now excludes the test layer.
  • tsconfig.test.json (new) compiles that layer under module: esnext / moduleResolution: bundler — the semantics vitest actually executes it with. That retires 22 x TS2835, the TS2347 beside them, and the share of TS7006 they cascade into: an import that does not resolve makes every symbol it names any. Strictness is inherited and untouched, and no test file is edited.
  • test-typecheck-debt.json (new) holds the residue of 4, per file and per signature, EXACT and shrink-only.
  • scripts/check-type-check-coverage.mjs — the @objectstack/core DEBT entry is deleted, because RECONCILED makes a DEBT entry for a package that declares typecheck an error.

The 4 ledgered are left deliberately, and the ledger's authored _note says why. Two are one defect twice over (src/plugin-loader.test.ts, src/security/plugin-permission-enforcer.test.ts: a mock PluginContext missing registerServiceFactory / replaceService / getServiceScoped) — the same shape the @objectstack/metadata DEBT entry records, whose repair is in flight on its own card, so the shared fixture they want should be authored once by whoever closes that rather than twice in parallel.

The examples/ half — found by the new script, not by the card

Declaring typecheck flips the package from COVERED-BY-LEDGER to COVERED-BY-SCRIPT, and check:type-check-coverage's SOURCES_COVERED invariant then reported packages/core/examples: 2 non-test source files in no tsc program at all. Neither had ever compiled — kernel-features-example.ts imported ../index.js (above the package root, never existed) and phase2-integration.ts imported @objectstack/core, i.e. this package self-referencing by a name it declares in no dependency block.

Collapsing that cascade exposed errors rather than removing them, 12 to 29 — all real, none new:

  • 20 reads of ObjectKernel's privatelogger;
  • 4 members of the security-scan result that do not exist (passed, score, summary.critical, summary.high, where KernelSecurityScanResult carries status and per-severity counts);
  • 2 config literals passing the unparsed shapes where PluginHealthMonitor.registerPlugin and HotReloadManager.registerPlugin are declared over the Parsed ones. That pair is retirement drift: this file was edited by two retirements (the PluginHealthCheck restart keys, and watchPatterns) while no tsc program could check the result.

Every correction is pinned to this package's own signatures — PluginPermissionSet off src/security/permission-manager.ts, the Parsed variants off src/health-monitor.ts / src/hot-reload.ts, the scan shape off the type tsc printed. packages/spec was not touched, and needed no change: the three types the example wanted are exported from @objectstack/spec/kernel, never from .../system, and this package's own source already imports them from kernel.

@objectstack/core therefore leaves the DEBT ledger: check:type-check-coverage now reads 70/79 type-checked with 9 ledgered, where it read 68/78 with 10.

Out of scope, reported not fixed

packages/core/examples/phase2-integration.ts is the sole composer of PluginSecurityScanner, which docs/qa/platform-checklist/FOLLOW-UPS.md already records as exported dead code on the public barrel with 3 of 5 scan methods empty stubs. When this directory was last found composing a retired surface, the repo deleted the example (api-registry-example.ts, #4939). Whether these two files should exist at all is a retirement decision for that seat; this PR only makes them compile, so the question is now visible to tsc instead of hidden from it.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and no path arguments, so the change set comes from the merge base rather than a hand-written list; harvested via --commands, not by grepping the prose. 49 families, all run at 27ecaa29e:

  • 45 green in the light batch, plus check:dual-build-cjs-loads and check:type-check-debt green.
  • pnpm --filter @objectstack/core typecheckexit 0 (the script this card is about).
  • check:type-check-debt20 ledger entr(ies) re-measured in 299.8s, 451 raw tsc error(s) total, none above its recorded number. surplus: none.
  • node scripts/pm/check-governed-merges.mjs --test on the final 9-file list — NOT governed.
  • 2 recorded NOT MEASURED, not red: check-test-completeness and check-half-states both exit 3 = PREREQUISITE NOT MET (a saved turbo run test log; GitHub API access). Neither is a finding, and both are unrelated to this diff.

⚠️ One local-only wrinkle worth naming: check:dual-build-cjs-loads first reported 2 findings against @objectstack/client and @objectstack/client-react. Both were artifacts of a cut-off local build (dist present, declarations not emitted); after building those two properly the gate is green over 102 entry points. Neither names @objectstack/core and this diff changes no exports map, no files, and no runtime source.

🤖 Generated with Claude Code

https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68


Generated by Claude Code

…d examples layers enter the ratchet (#14613)
`packages/core/package.json` declared exactly `build`, `test`, `test:watch`.
`turbo run typecheck` selects only packages that declare the task, so the lint
workflow's typecheck job could not reach this package and
`pnpm --filter @objectstack/core typecheck` failed with
ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT for anyone who tried it.
Measured at 84b8190, dependency closure built first:
- `tsc --noEmit -p tsconfig.json` (tests included, as the DEBT entry
measured it): 98 errors over 12 files, all 12 of them `.test.ts`
- the same program over only the 63 non-test source files: ZERO
- the same 48 test files under vitest's module semantics: 4
So 94 of the 98 were the CHECK, not the code, and NO TEST FILE IS EDITED here.
`tsconfig.json` keeps the build layer and excludes tests; a new
`tsconfig.test.json` compiles them under `module: esnext` /
`moduleResolution: bundler`, retiring 22 x TS2835, the TS2347 beside them and
the TS7006 cascade they cause. Strictness is inherited and untouched. The
residue of 4 is held per file and per signature in `test-typecheck-debt.json`,
EXACT and shrink-only.
Declaring the script flips the package from COVERED-BY-LEDGER to
COVERED-BY-SCRIPT, so `check:type-check-coverage`'s SOURCES_COVERED invariant
then reported `packages/core/examples` -- 2 non-test source files in NO tsc
program. Neither had ever compiled (`../index.js` resolves above the package
root; `@objectstack/core` is this package self-referencing by a name it declares
in no dependency block). Collapsing that cascade EXPOSED errors, 12 -> 29: 20
reads of ObjectKernel's private `logger`, four scan-result members that do not
exist, and two config literals passing unparsed shapes where the methods are
declared over the `Parsed` ones -- drift from two retirements that edited this
file while no tsc program could check it. Every correction is pinned to this
package's own signatures; `packages/spec` was not touched.
`@objectstack/core` therefore leaves the DEBT ledger: the coverage gate reads
70/79 type-checked with 9 ledgered, where it read 68/78 with 10.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 4 documentable anchor(s). ⚠️3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/lifecycle.mdx(via installPlugin (symbol, a method of class EnterprisePluginPlatform))
What this run could not see
  • 3 changed file(s) yielded no anchor (packages/core/test-typecheck-debt.json, packages/core/tsconfig.examples.json, packages/core/tsconfig.json) — pages documenting those are invisible to this run
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fcpackageMentionDocs.

Which tree this was computed on

This run read content/docs from 000a8b2396d77613e3506148fbad7b8072257e01 — the merge of head 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 into base 09cc6be43414214b9abfc7791b8497ea4f9dd2fc, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 000a8b2396d77613e3506148fbad7b8072257e01 && git checkout 000a8b2396d77613e3506148fbad7b8072257e01
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 09cc6be43414214b9abfc7791b8497ea4f9dd2fc 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336 && git checkout -B drift-repro 09cc6be43414214b9abfc7791b8497ea4f9dd2fc && git merge --no-ff 86d7cc58b2615bf4cd0fe2de6a0c0856102f0336
node scripts/docs-audit/affected-docs.mjs --json 09cc6be43414214b9abfc7791b8497ea4f9dd2fc

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 09cc6be43414214b9abfc7791b8497ea4f9dd2fc → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…R_MANAGED
check:merge-driver red on PR #14916: gen:test-typecheck-debt (added to
@objectstack/core by #14613) had no recorded merge disposition in either
ledger in scripts/regen-artifacts.mjs.
packages/core/test-typecheck-debt.json is the same shrink-only, per-signature
EXACT ratchet as its six siblings already routed to NOT_DRIVER_MANAGED
(spec, client, rest, objectql, the plugin family, lint, runtime) — a
mid-merge "discard both sides and regenerate" would record whatever the
half-merged tree happens to compile to, turning a real GAINED-error red into
merge noise. It also carries the family's clearest example of the second
hazard: a hand-authored `_note` (never written by `--update`, only ever
preserved verbatim from an existing file) recording a human's triage of all
4 entries — 2 deferred to a shared-fixture repair in flight on
@objectstack/metadata, 1 a genuine open design question, 1 left unfixed on
purpose for diff cleanliness — plus why the ledger opens at 4 rather than
the 98 the retired check:type-check-coverage DEBT entry once measured (94 of
those 98 were a NodeNext config artifact this PR's tsconfig.test.json fixes,
not test debt). None of that triage is reconstructable from source.
Verified: only one new generator (gen:test-typecheck-debt) was added by
#14613's diff; check:test-typecheck and typecheck are non-generator scripts
and need no disposition. `pnpm check:merge-driver` is green, both legs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
…re-typecheck-script
# Conflicts:
#	scripts/regen-artifacts.mjs
@os-musk
os-musk marked this pull request as ready for review September 3, 2026 16:17
@os-musk
os-musk enabled auto-merge September 3, 2026 16:17
@os-musk
os-musk added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 8120808Sep 3, 2026
36 checks passed
@os-musk
os-musk deleted the claude/issue-14613-core-typecheck-script branch September 3, 2026 16:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] @objectstack/core declares no typecheck script, so no CI job ever type-checks it — and its own tsconfig program is currently red

2 participants

@os-musk@claude