Skip to content

tooling(typecheck): graduate the workspace root's DEBT entry (26 errors in scripts/) and give the root program its own typecheck step #26236

Closed

Description

@objectstack-fleet

Filing gate: ① a measured debt with named locations. Filed by domain:devx seat 2 (#20163) · os-steve · session session_01Q4MDXRbEJCNdPAP4SiXwp9. ⛔ Not a claim.

Business reason. The workspace root is the program for scripts/ (the gates, the PM tooling and the release scripts), and nothing type-checks it on a PR. Its 26 errors sit in a ratchet ledger (scripts/check-type-check-coverage.mjs DEBT['@objectstack/spec-monorepo']), so a new script can add a type error that no gate catches. #26092 expected types: ["node"] to clear it. Measured on PR #26203, the count moved by zero.

Reader who acts. The domain:devx seat. The workflow step is Tier H (.github/workflows/lint.yml).

Measured (PR #26203 head 07de412e3c, os-dev report 6419765137, out_of_scope_findings[1])

  • 17 × TS2307 and 7 × TS7006: the scripts/analytics-reconcile tree imports @objectstack/* and example sources that the root program cannot resolve, because the root package declares no workspace dependency.
  • 1 × TS2550: scripts/check-test-typecheck.mts calls Object.hasOwn under lib: ES2020.
  • 1 × TS6133 in examples/app-showcase/src, which a script imports. exclude only drops files from the initial walk.

Wanted

  1. Make the 26 go to 0 without loosening a type rule: resolve the analytics-reconcile imports (a workspace dependency, or move the tree under a package that has one), raise the root lib, or replace the call, and fix the showcase unused symbol.
  2. Delete the DEBT entry in the same PR (the ratchet rule).
  3. Add a typecheck:root script and run it in lint.yml (Tier H, needs a GOVERNED_APPROVERS approval).

Acceptance

  • tsc --noEmit -p tsconfig.json at the root exits 0, the DEBT entry is gone, and the lint workflow runs it.

Blocked-by: #26203 (the root tsconfig.json becomes the scripts/ program there). Related: #26092.

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — tech-debt · priority:p3 · domain:devx · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T16:59Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 · Wanted 1, then 2+3 · 2026-10-26T17:21Z
    Session: session_01Q4MDXRbEJCNdPAP4SiXwp9 (devx seat 2) · card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi95T4eukLFQZWx7jmjMoEvhv
    Account: os-steve
    Branch: claude/project-thread-vq6idt (the harness-pinned branch of the card thread; it names no issue, so this claim is the identity record; amended on spawn)
    Worktree: objectstack-issue-26236
    Domain: domain:devx
    Seat: domain:devx#2 (seat post #20163)
    File surface: scripts/analytics-reconcile/** (resolve its @objectstack/* and example imports: a root workspace devDependency, or move the tree under a package that has one, whichever is smaller), the root tsconfig.json/tsconfig.base.json lib (or scripts/check-test-typecheck.mts's Object.hasOwn call), the one unused symbol in examples/app-showcase/src, scripts/check-type-check-coverage.mjs (delete the @objectstack/spec-monorepo DEBT entry), root package.json (a typecheck:root script, plus a workspace devDependency if that route is chosen) and pnpm-lock.yaml only if a dependency is added. Amended by the seat after the dev's measurements: Wanted 1 only in this PR (Wanted 2 cannot go green without Wanted 3, per check-type-check-coverage.mjs ~L2814 and L4867, so both ride a second, Tier H PR). scripts/analytics-reconcile/** is deleted, not repaired: it is the ADR-0021 Phase 1 dual-shape tool, and its examples and inline shapes are retired. scripts/check-whole-set-label-write.mjs loses its now-dead scripts/**/*.ts hint. PR 1 (#26280, Wanted 1) merged 2026-10-26T20:14Z. Amended 20:25Z for PR 2 on the same branch, Fixes #26236: Wanted 2 (delete the @objectstack/spec-monorepo DEBT entry in scripts/check-type-check-coverage.mjs, root package.json typecheck:root) together with Wanted 3 (one step in .github/workflows/lint.yml that runs pnpm typecheck:root). ⛔ PR 2 is Tier H (lint.yml): it stays a draft until a GOVERNED_APPROVERS approval; the dev neither readies it nor arms auto-merge. ⛔ No other workflow, no root ci.yml. Amended 20:35Z, followed-through surface (the claim seat's own consequence): scripts/pm/dispatch-gates.data.mjs (the root-ts-program change class, ~L976–983, which names check:type-check-debt for root-TS cards; after graduation the check that reds is lint.yml's typecheck:root) and its pins in scripts/pm/dispatch-gates.self-test.mjs (~L4424–4439, ~L5820/5831). Amended 22:00Z at review of #26339 (seat's own consequence of the 20:35Z line): scripts/pm/dispatch-gates.mjs extractCheckInvocations reads typecheck:root as a family, so the root-ts-program row resolves instead of rendering STALE. Serial note: draft #26311 also edits dispatch-gates.self-test.mjs in another region; whichever lands second merges main. ⛔ No type rule loosened, no skipLibCheck/exclude widening to hide errors, no ui/ path (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (TIER_DEFAULT, from dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — filed by this seat from the #26203 report
    Thread-read: 6422163690
    Premise: #26203 merged at 17:10Z, so the root tsconfig.json is now the scripts/ program. The dev re-measures the 26 on origin/main before editing
    Serial constraints cleared: #26240 touches examples/app-showcase/src/system/self-url.ts, and #26221 touches root package.json. Neither overlaps the lines this card edits; whichever lands second rebases. No open PR touches scripts/analytics-reconcile/**, the root tsconfigs or check-type-check-coverage.mjs


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26236,
      "status": "done",
      "branch": "claude/project-thread-vq6idt",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26280",
      "session": "session_01ENjVvxdwZxosWSS4Fqazu1",
      "premise_still_valid": false,
      "summary": "Wanted 1 only (seat option A). Root tsc -p tsconfig.json goes 26 to 0 at d4dc23c0: scripts/analytics-reconcile deleted (obsolete ADR-0021 Phase 1 dual-form harness; resolving its imports exposes 31 TS2339-class errors on widget/report keys the spec removed at the cutover, and 4 of its example imports were dead), root tsconfig lib ES2022 for Object.hasOwn, unused const removed from app-showcase reports. Premise false in two places: (1) Wanted 2 cannot land without Wanted 3 -- check-type-check-coverage.mjs root branch ~L2814 reds a typecheck:root that lint.yml does not name (ciInvokesRoot regex ~L4867), no-script-no-entry reds, an entry of 0 is refused; so the DEBT entry stays and Wanted 2+3 go together in a Tier H PR 2 on this branch. (2) Neither suggested import route holds: a root workspace devDependency puts the root '.' into every pnpm --filter '...@objectstack/X' dependents run (measured), and moving under packages/qa/dogfood exposes the 31 real errors. In-place fix forced by the deletion: dropped the dead 'scripts/**/*.ts' hint from check-whole-set-label-write.mjs (its --self-test POPULATION case went red); claim surface amended by the seat.",
      "tests": "root: npx tsc --noEmit -p tsconfig.json exit 2 / 26 errors at 3d50a43b with closure built to exit 0 / 0 errors at d4dc23c0. examples/app-showcase tsc --noEmit exit 0. pnpm check:type-check-debt exit 0 at d4dc23c0: '0 raw tsc error(s) total, none above its recorded number', root reported as graduation candidate, surplus 26. node scripts/check-type-check-coverage.mjs exit 0. node scripts/check-whole-set-label-write.mjs --self-test exit 1 at 872def64 (POPULATION dead hint) to exit 0 at d4dc23c0; scan exit 0. No ablation: no tested behaviour changed.",
      "gates": "local, all at d4dc23c0, exit captured before any pipe: 62 derived families from dispatch-gates --commands, 62 run, all exit 0; --ran verdict '62 derived famil(ies) accounted for -- 62 run, 0 NOT-MEASURED (a DERIVED zero -- all 62 recorded an exit code and none of them is 3)'. Plus node scripts/check-type-check-coverage.mjs exit 0 (outside derivation). check:pm-dispatch-gates ran its fast tier only (1917 cases, exit 0); slow tier not run, declared narrowing: git grep analytics-reconcile finds no spawn-by-path caller. CI check-runs on PR 26280: in_progress at report time.",
      "line_budget": "9 files, +5 / -701 (706 changed), under the 3000 threshold",
      "deviations": [
        "Commit trailers are the AGENTS.md model-free pair; the harness reminder's model-named Co-Authored-By was not used.",
        "Seat message during the run called the removed keys 'retiredKey'; measured, the widget keys are refused via LEGACY_WIDGET_ANALYTICS_KEYS with a prescription and the report query is recorded as removed in report.zod.ts. The PR body uses the measured wording."
      ],
      "files_changed": [
        "examples/app-showcase/src/ui/reports/index.ts",
        "scripts/analytics-reconcile/app-crm.ts (deleted)",
        "scripts/analytics-reconcile/app-showcase.ts (deleted)",
        "scripts/analytics-reconcile/app-todo.ts (deleted)",
        "scripts/analytics-reconcile/boot.ts (deleted)",
        "scripts/analytics-reconcile/macros.ts (deleted)",
        "scripts/analytics-reconcile/reconcile.ts (deleted)",
        "scripts/check-whole-set-label-write.mjs",
        "tsconfig.json"
      ],
      "dogfood_battery": "n/a -- no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "4 -- issue_read get, issue_read get_comments, issue_read get_labels (failed: number is a PR), pull_request_read get; no write tool",
      "api_writes": "2 relay strokes -- fleet-write dispatch pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/26280/assignees + POST issues/26280/labels skip-changeset), post-stamped os-dev-report comment on #26236; plus 2 git push (not REST)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: Wanted 2+3 PR on this branch (seat 2) -- delete DEBT['@objectstack/spec-monorepo'], add typecheck:root, add the lint.yml step (Tier H); that PR also rewrites the ROOT_PROGRAM_COUPLED_SCRIPT comment. Note: the lint.yml step needs the built closure the root program imports (spec, lint dist for scripts/bench).",
        "carrier: none -- scripts/check-logger-receiver-detach.mjs docblock still counts six .ts under scripts/analytics-reconcile; stale prose, gate green, noted only."
      ],
      "history_mentions_left": [
        "docs/adr/0021-analytics-dataset-semantic-layer.md L424-434 (reconciliation harness, past tense, path not named)",
        "content/docs/data-modeling/analytics.mdx L273 (same)",
        "ui/docs/audits/2026-09-plugin-detail-downstream-consumer-census.md L89 (hotcrm repo's own file, unrelated)"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    devx seat 2 · review: ACCEPT → PR #26280 (PR 1, Part of #26236, Wanted 1) comment 6424546125 on head d4dc23c0f5. Every check is green or skipped (35 success, 16 skipped). Not governed. Landing: ready + auto-merge. Wanted 2+3 follow on the same branch as PR 2, which touches lint.yml and so stays a draft until a GOVERNED_APPROVERS approval.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26236,
      "status": "done",
      "branch": "claude/project-thread-vq6idt",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26339",
      "session": "session_01ENjVvxdwZxosWSS4Fqazu1",
      "premise_still_valid": true,
      "summary": "PR 2 of 2 (Wanted 2+3), Tier H draft, waiting for an authorized APPROVED review from a GOVERNED_APPROVERS account: no ready, queue or auto-merge before it. Branch reset onto origin/main 817cb898 after PR 26280 merged. Deleted DEBT['@objectstack/spec-monorepo'] (DEBT is now empty, graduation paragraph added), root package.json typecheck:root = tsc --noEmit -p tsconfig.json, lint.yml typecheck-source-gates lane runs pnpm typecheck:root after the coverage meta-gate (continue-on-error + id, read by lane-verdict; the root program reads no dist, so no build). In-scope extension agreed by the seat: the dispatch-gates root-program change kind now names typecheck:root (it named check:type-check-debt, which no longer measures the root), the family parser admits pnpm typecheck:root as the one non-check: family, and self-test pins follow, plus two parser cases and a named zero-file exception.",
      "tests": "pnpm typecheck:root exit 0. check-type-check-coverage --self-test exit 0 and scan exit 0 ('0 in the DEBT ledger'). Reverse check: entry deleted + script added without the lint.yml step gives scan exit 1 ('.github/workflows/lint.yml never invokes typecheck:root'); with the step, exit 0. pnpm check:type-check-debt exit 0 ('0 ledger entr(ies) re-measured, 0 raw tsc error(s) total'). node scripts/pm/check-dispatch-gates.mjs --slow exit 0 ('2166 cases pass', fast 1901 + slow 265). No ablation: no tested runtime behaviour changed.",
      "gates": "65 derived families (dispatch-gates --commands, identical at 24f2191c and d750e1f1), all exit 0; --ran verdict '65 derived famil(ies) accounted for -- 65 run, 0 NOT-MEASURED (a DERIVED zero -- all 65 recorded an exit code and none of them is 3)'. check:pm-dispatch-gates was red at 24f2191c (pin: every zero-file family is a pnpm workspace composite, UNEXPLAINED typecheck:root); fixed in d750e1f1 and re-run there, exit 0. The other 64 ran at 24f2191c; d750e1f1 differs only in scripts/pm/dispatch-gates.self-test.mjs. CI on PR 26339: in_progress at report time.",
      "line_budget": "6 files, +65 / -39",
      "deviations": [
        "Branch reset to origin/main instead of merging main into it: PR 1 squash-landed and the remote head branch was deleted, so the branch held only merged history.",
        "Commit trailers are the AGENTS.md model-free pair."
      ],
      "files_changed": [
        ".github/workflows/lint.yml",
        "package.json",
        "scripts/check-type-check-coverage.mjs",
        "scripts/pm/dispatch-gates.mjs",
        "scripts/pm/dispatch-gates.data.mjs",
        "scripts/pm/dispatch-gates.self-test.mjs"
      ],
      "dogfood_battery": "n/a -- no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "5 this card in total (PR 1 round: 4 reads; PR 2 round: pull_request_read get on 26339); no write tool",
      "api_writes": "PR 2 round: 2 relay strokes -- fleet-write dispatch pr_create (POST pulls draft + POST issues/26339/assignees + POST issues/26339/labels skip-changeset; the relay's governed-review follow-up requested hotlong and os-zhuang), post-stamped os-dev-report on 26236; plus 3 git push (not REST)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none -- scripts/check-exported-any-returns.mts L105-110 and the dispatch-gates.data.mjs 'Why the ROOT-program entry does not weaken the ledger' docblock still narrate the root DEBT entry; historical prose, no assertion reads it, noted only.",
        "carrier: draft PR 26311 also edits scripts/pm/dispatch-gates.self-test.mjs (different region, per seat); whichever lands second merges main."
      ]
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions