[finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

Description

@os-musk

Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

1. The mechanism — the ratchet skips depth 0

scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
...
}

depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

fileshapeprogram that reads it
packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

The three example apps put their root config inside the program and have done so for a while:

  • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
  • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
  • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

What a fix looks like

  1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
  2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
  3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , '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

    [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

    Description

    @os-musk

    Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

    1. The mechanism — the ratchet skips depth 0

    scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

    functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
    ...
    }

    depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

    The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

    ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

    2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

    104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

    fileshapeprogram that reads it
    packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
    packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
    packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

    ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

    packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

    3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

    The three example apps put their root config inside the program and have done so for a while:

    • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
    • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
    • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

    None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

    What a fix looks like

    1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
    2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
    3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

    ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

    Metadata

    Metadata

    Assignees

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , '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

      [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

      Description

      @os-musk

      Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

      1. The mechanism — the ratchet skips depth 0

      scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

      functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
      ...
      }

      depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

      The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

      ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

      2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

      104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

      fileshapeprogram that reads it
      packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
      packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
      packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

      ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

      packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

      3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

      The three example apps put their root config inside the program and have done so for a while:

      • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
      • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
      • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

      None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

      What a fix looks like

      1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
      2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
      3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

      ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

      Metadata

      Metadata

      Assignees

      Type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , '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

        [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

        Description

        @os-musk

        Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

        1. The mechanism — the ratchet skips depth 0

        scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

        functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
        ...
        }

        depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

        The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

        ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

        2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

        104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

        fileshapeprogram that reads it
        packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
        packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
        packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

        ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

        packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

        3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

        The three example apps put their root config inside the program and have done so for a while:

        • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
        • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
        • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

        None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

        What a fix looks like

        1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
        2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
        3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

        ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

        Metadata

        Metadata

        Assignees

        Type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , '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

          [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

          Description

          @os-musk

          Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

          1. The mechanism — the ratchet skips depth 0

          scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

          functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
          ...
          }

          depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

          The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

          ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

          2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

          104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

          fileshapeprogram that reads it
          packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
          packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
          packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

          ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

          packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

          3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

          The three example apps put their root config inside the program and have done so for a while:

          • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
          • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
          • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

          None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

          What a fix looks like

          1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
          2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
          3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

          ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

          Metadata

          Metadata

          Assignees

          Type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , '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

            [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

            Description

            @os-musk

            Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

            1. The mechanism — the ratchet skips depth 0

            scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

            functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
            ...
            }

            depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

            The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

            ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

            2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

            104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

            fileshapeprogram that reads it
            packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
            packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
            packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

            ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

            packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

            3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

            The three example apps put their root config inside the program and have done so for a while:

            • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
            • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
            • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

            None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

            What a fix looks like

            1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
            2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
            3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

            ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

            Metadata

            Metadata

            Assignees

            Type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , '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

              [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

              Description

              @os-musk

              Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

              1. The mechanism — the ratchet skips depth 0

              scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

              functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
              ...
              }

              depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

              The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

              ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

              2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

              104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

              fileshapeprogram that reads it
              packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
              packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
              packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

              ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

              packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

              3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

              The three example apps put their root config inside the program and have done so for a while:

              • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
              • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
              • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

              None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

              What a fix looks like

              1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
              2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
              3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

              ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

              Metadata

              Metadata

              Assignees

              Type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , '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

                [finding] check:type-check-coverage cannot see PACKAGE-ROOT source (depth 0 is skipped by construction) — three more objectstack.config.ts manifest sites sit outside every tsc program with no ledger entry #14386

                Description

                @os-musk

                Found while implementing #13284 (which puts driver-memory / plugin-hono-server's objectstack.config.ts inside a tsc program). Filed rather than fixed: #13284's file surface is fenced to those two packages, and the repair here is not mechanical — it changes what the coverage ratchet reports for a population of 104 files across the whole workspace, which is a decision, not an edit. Measured on origin/main@d62f990a.

                1. The mechanism — the ratchet skips depth 0

                scripts/check-type-check-coverage.mjs builds SOURCES_COVERED's input from a package walk whose file predicate is:

                functionisUncheckedSourceCandidate(name,depth){if(depth===0)returnfalse;
                ...
                }

                depth === 0 is the package root. So a non-test .ts file sitting at a package root and read by no tsc program is invisible to the invariant whose whole job is "every workspace package's TypeScript is read by tsc somewhere, or its absence is a recorded, tracked decision". It is not reported, and it earns no UNCHECKED_SOURCE_DEBT entry, so it is not tracked either.

                The aggregation is directory-granular in the same way — uncheckedByDir keys on rel.slice(0, rel.indexOf('/')), which has no key for a root-level file even if the predicate admitted one.

                ⇒ This is exactly why #13284 was invisible for as long as it was: pnpm --filter @objectstack/driver-memory typecheck exited 0 with a file that imported a symbol its entry does not export, and check:type-check-coverage reported the package COVERED at the same time. Both gates were green over an unread file.

                2. The population — 104 package-root .ts files, and 3 of them are live manifest authoring sites

                104 non-test, non-.d.ts.ts files sit at a package root across packages/, apps/ and examples/. Most are build/test tooling (vitest.config.ts, tsup.config.ts), and whether those belong in a program is the decision this card asks for. Three are not tooling — they are plugin manifest authoring sites of exactly the class #13284 is about, and all three are outside every tsc program their package's typecheck script runs:

                fileshapeprogram that reads it
                packages/plugins/plugin-auth/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — tsconfig.json is include: ["src/**/*"]
                packages/plugins/plugin-security/objectstack.config.tsdefineStack({ ... }), composing ./src/manifestnone — same
                packages/services/service-i18n/objectstack.config.tsdefineStack({ manifest: { ... inline ... } })none — include: ["src"]

                ⚠️ Note for whoever triages: #13284's framing that its two files are "the only places in this repo where a plugin manifest is authored in TypeScript" is inaccurate — there are five package-level sites, not two. The other three differ in a way that softens but does not remove the defect: they call defineStack(...), so the manifest is checked against that function's parameter type if anything ever compiles the call, and today nothing does. service-i18n's is the sharpest of the three, because its manifest body is authored inline rather than imported from src/.

                packages/services/service-i18n also runs a bare typecheck: "tsc --noEmit" with a single config, so it has no sibling program to extend.

                3. The repo already has both shapes, which is why this reads as an oversight rather than a policy

                The three example apps put their root config inside the program and have done so for a while:

                • examples/app-crm/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*", "vitest.config.ts"], noEmit: true
                • examples/app-showcase/tsconfig.jsoninclude: [..., "objectstack.config.ts", "playwright.config.ts", ...], noEmit: true
                • examples/app-todo/tsconfig.jsoninclude: ["src/**/*", "objectstack.config.ts", "test/**/*"], rootDir: "."

                None of them carries an emitting rootDir: "./src", which is the constraint that forces a sibling noEmit program in the packages that do (measured on #13284: adding the file to the emitting config raises TS6059 in both packages, under --noEmit too).

                What a fix looks like

                1. Decide what a package-root .ts file owes. The honest options are: admit depth 0 into isUncheckedSourceCandidate and give the aggregation a key for the root (then every un-programmed vitest.config.ts / tsup.config.ts needs either a program or a ledger entry — that is the 104-file bill), or admit depth 0 only for a declared set of root filenames that are real authored source rather than build tooling (objectstack.config.ts first among them).
                2. Whichever is chosen, add a --self-test case for a root-level source file — the gate's existing source-layer cases are all subdirectory cases (packages/a/scripts), which is why the hole survived.
                3. Put the three sites above into a program, following whichever shape their rootDir allows (sibling noEmit program where the build config emits from ./src; a widened include where it does not).

                ⛔ Not a duplicate of #4311 (framework-wide "tsup-built packages nobody typechecks"), #14062 (no plugin package compiles its tests) or #14342 (@objectstack/metadata has no typecheck script at all): every one of those is about a package or a layer the gate CAN see and reports on. This one is about source the gate's own observation half cannot reach, in packages it counts as fully COVERED.

                Metadata

                Metadata

                Assignees

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions