Uh oh!
There was an error while loading. Please reload this page.
fix(service-automation): compile the test layer with tsc, and repair the TS2341 x3 it hid - #15152
Conversation
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…rvice-automation-typecheck # Conflicts: # scripts/check-type-check-coverage.mjs
… tree The `service-knowledge` onboarding landed on `main` between this entry's first reading and this merge, so every absolute in its provenance block (programs, pairs, packages, clean count) was a number about a tree that no longer exists. Re-taken with `--list` on the merge commit itself, all four rows plus the before/after pair, by varying only what the `typecheck` script names: no `typecheck` script absent 120 programs / 293 pairs names tsconfig.json absent 120 programs / 293 pairs names tsconfig.test PRESENT 121 programs / 302 pairs names both (the card) PRESENT 121 programs / 302 pairs before 59 of 78 packages, 120 programs, 293 pairs, 19 clean after 60 of 78 packages, 121 programs, 302 pairs, 18 clean The deltas this block actually claims (+1 package, +1 program, +9 pairs, one per dep) are unchanged; only the absolutes moved, and the block now says which merge moved them. The sibling entries' own blocks keep their own historical readings untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y
os-warren
commented
Sep 4, 2026
Merge round — conflicted against |
typecheck names | entry | --list totals |
|---|---|---|
| nothing (origin/main) | absent | 120 programs / 293 pairs (59/78 packages, 19 clean) |
tsconfig.json only | absent | 120 programs / 293 pairs (59/78, 19 clean) |
tsconfig.test.json only | PRESENT | 121 programs / 302 pairs (60/78, 18 clean) |
| both (this PR) | PRESENT | 121 programs / 302 pairs (60/78, 18 clean) |
before 59/78 packages, 120 programs, 293 pairs, 19 clean → after 60/78, 121, 302, 18 clean, i.e. +1 package, +1 program, +9 pairs (one per dep), this entry and nothing else — the deltas the block actually claims are unchanged; only the absolutes moved. Commit c6d25b73 writes exactly these into this entry's own doc-block and says which merge moved them. The service-cluster, service-i18n and service-knowledge blocks keep their own historical readings untouched.
The DEBT ledger summary line moved for the same reason — two packages graduated where the reviewed round had one:
check-type-check-coverage: OK — 74/79 workspace packages type-checked (plus the root),
5 in the DEBT ledger (104 frozen raw errors, …), 1 exempt.
(The body above reads 6 in DEBT / 114 frozen; that was true of the pre-merge tree.)
Gates re-run on the merged head c6d25b73
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, re-derived against the post-merge diff (7 paths, merge base 919beca43) → 64 commands. Every exit code captured redirect-then-read, never across a pipe; verdict lines read rather than bare status. 62 exit 0, 2 NOT MEASURED (exit 3), 0 findings.
pnpm check:type-check-coverage— exit 0, quoted above; its--self-testleg reports 48 semantic + 68 observation + 45 re-measure + 28 built-closure + 19 auto-lowering + 18 exit-code cases holding.pnpm check:type-source-resolution— exit 0:check-type-source-resolution OK — 121 tsc program(s) across 78 packages scanned …; 60 registered as still resolving a workspace dep's types through dist/.(self-test leg OK.)pnpm --filter @objectstack/service-automation typecheck— exit 0:check:test-typecheck: OK — @objectstack/service-automation's test layer compiles under packages/services/service-automation/tsconfig.test.json; 0 file(s) / 0 error(s) / 0 pinned signature(s).pnpm --filter @objectstack/service-automation test— exit 0: 103 test files / 1225 tests passed, identical to the reviewed round.pnpm check:nul-bytes— exit 0, plus a hand scan of both edited scripts for raw control bytes: no matches.
NOT MEASURED, quoting each gate's own verdict rather than a bare status:
pnpm check:dual-build-cjs-loads— exit 3: "PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/. … Runpnpm buildfirst. This is NOT a pass: nothing was measured."pnpm check:type-check-debt— exit 3: "--re-measure cannot run: 13 workspace dependenc(ies) of the ledgered packages have no built type entry point on disk … Build the closure first, exactly as lint.yml does before this step." Its--self-testleg ran and passed before the refusal.
Both want a full-workspace build, which is CI's job rather than a per-package dependency closure — the same two NOT MEASURED results the reviewed round recorded, unchanged in kind by the merge.
One further note for the record: node scripts/check-plugin-teardown-shape.mjs --self-test exited 1 once inside the batch, refusing with "cannot read the positive control" and declining to print a verdict. Re-run unhurried on the same tree it exits 0 with all 47 cases passing, and the clone is not shallow and does hold the pinned fixture commit — a transient read under load, not a finding.
Generated by Claude Code
Uh oh!
There was an error while loading. Please reload this page.
Resolves the third and last conflict of the #14062 family. Both siblings have landed on main (#15147 service-knowledge, #15152 service-automation) and all three touch the same two gate scripts. Resolution is "keep every entry" -- the three cards do not disagree: * scripts/check-type-check-coverage.mjs: all three graduation paragraphs kept above `DEBT` (service-storage first, so the service-knowledge paragraph's "the paragraph above ... for `metadata` and `service-storage`" back-reference still resolves), and all three DEBT entries deleted. The ledger summary line is computed at runtime from DEBT/TEST_DEBT, so no hand-edited total exists there to reconcile. * scripts/check-type-source-resolution.mjs: auto-merged; all three new registry entries present, service-cluster / service-i18n untouched. * pnpm-lock.yaml: not hand-merged. `pnpm install` over the merged manifest set leaves the auto-merged file byte-identical (hash 000bb7d...) and `pnpm install --frozen-lockfile` exits 0. The diff against main is unchanged from the reviewed one: same 20 files, same +307/-133. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y
…the TS2341 x3 it hid (#15152) * wip: onboard service-automation typecheck, fix TS2341 residue * wip: onboarding gate registry entry + changeset * fix(scripts): re-measure this entry's provenance totals on the merged tree The `service-knowledge` onboarding landed on `main` between this entry's first reading and this merge, so every absolute in its provenance block (programs, pairs, packages, clean count) was a number about a tree that no longer exists. Re-taken with `--list` on the merge commit itself, all four rows plus the before/after pair, by varying only what the `typecheck` script names: no `typecheck` script absent 120 programs / 293 pairs names tsconfig.json absent 120 programs / 293 pairs names tsconfig.test PRESENT 121 programs / 302 pairs names both (the card) PRESENT 121 programs / 302 pairs before 59 of 78 packages, 120 programs, 293 pairs, 19 clean after 60 of 78 packages, 121 programs, 302 pairs, 18 clean The deltas this block actually claims (+1 package, +1 program, +9 pairs, one per dep) are unchanged; only the absolutes moved, and the block now says which merge moved them. The sibling entries' own blocks keep their own historical readings untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y --------- Co-authored-by: Claude <noreply@anthropic.com>
Fixes#15048
packages/services/service-automationhad notypecheckscript at all (its scripts werebuildandtest), so no tsc program anywhere read this package. Turbo/CI typecheck lanes skipped it silently, because a zero-matching filter run exits 0.tsuptranspiles with esbuild andvitestruns through esbuild type-stripping; neither type-checks.Clause-②: no
The route, and which exemplar it was copied from
Copied from
plugin-webhooks/service-cluster(#14181, PR #15032), not fromplugin-auth/plugin-sharing/core, because it is the structural match. The deciding property is what the BUILD config does with tests:tsconfig.jsonexcludes tests?plugin-auth,plugin-sharing**/*.test.tsinexclude)core(#14916)**/*.spec.ts,**/*.test.ts)test-typecheck-debt.json, 4 residualplugin-webhooks,service-clusterservice-automationservice-automation'stsconfig.jsonincludes the tests and always did (include: ["src"], no test exclusion), so the program that would have read them already existed and was simply never invoked. It is therefore not a package that needs an exclusion compensated for, and AGENTS.md is explicit in the other direction: "Neverexclude*.test.ts/*.spec.tsfrom a package'stsconfig.json". Sotsconfig.jsonis untouched, and the siblingtsconfig.test.jsonis the family's uniform instrument over the same files.The sibling changes module semantics only (
module: esnext,moduleResolution: bundler,lib: ES2022, matching how vitest actually executes these files). Strictness is inherited and untouched, and it declares nopaths.Measured error count, before and after
Dependency closure built first (
pnpm --filter '@objectstack/service-automation^...' build), measured at2cc4610304(origin/main):tsc --noEmit -p tsconfig.json, which already included the tests)tsc --noEmit -p tsconfig.test.json)555 files in the program, covering all 103 of the package's
src/**/*.test.ts.The two readings agree, and that agreement is the load-bearing result — same as
service-cluster's own graduation, and unlike@objectstack/core(#14916: 98 undivided → 4 after the split, nearly all TS7006 cascading from one unresolved import). This package carried no config-tier pile at all; the 3 were genuinely code-tier from the start, well inside the dispatch's "a handful, fix them properly" branch, so no stop-and-report was owed.The three errors, and why the fix is correct rather than convenient
All three were
TS2341("Property 'flows' is private and only accessible within class 'AutomationEngine'"), all insrc/nested-region-parity.test.ts(lines 95/151/180):Three tests dot-read the class's private
flowsmap (engine.flows.get(name)) directly, instead of going through its own public accessor:That accessor already exists, and it is already the idiom every other test file in this package uses (
await engine.getFlow(name)— 10+ call sites acrossengine.test.ts,canonicalize-stored-flow.test.ts,flow-cold-boot-bind.test.ts,flow-load-conversion.test.ts, etc.). The fix is therefore not a workaround: it replaces three private-internals reads with the public surface the class already offers, matching the rest of the suite — no source signature widened, no cast, no bracket-notation trick.The two test bodies that were not already
asyncwere madeasynctoawaitthe accessor. Re-ran the file after the fix: 22/22 tests pass, unchanged behavior — the assertions test the same thing, only the read reaches it through the public door.Ledger consequences
DEBTentry deleted, not lowered.check-type-check-coverage.mjscarried'@objectstack/service-automation': { errors: 3, note: 'code-tier 3 (TS2341 x3)...' }. That gate's own invariant is "covered packages must not also sit in the ledger". The entry is deleted and the graduation recorded in the file's prose. Gate now reads 5 in DEBT where it read 6 (104 frozen errors, down from 114), on the merged tree.test-typecheck-debt.jsonis created, and its absence is the zero: any error in any file here is red immediately, with no entry to be added to. ⛔ No ledger was grown in either direction.check:type-source-resolution— a re-baseline, please review it as oneThis gate goes red on this diff as expected (the card's own⚠️ block flags this), and the remedy its failure text names (
paths) is measurably the wrong one here too — same finding asservice-cluster's own re-baseline, reproduced at larger scale because this package pulls 9 workspace deps instead of 2.Provenance, measured four ways on one checkout, varying only what
typechecknames:typechecknames--listtotalstsconfig.jsononlytsconfig.test.jsononlyRow 2 is the load-bearing one:
tsconfig.jsonis always a counted program per this gate's own design (programConfigsFor's doc-block), and it already includes every test file — yet it measures clean, with zero dist-resolved workspace type imports. So the exposure is only reachable through the onboardedtsconfig.test.jsonprogram, not merely first seen there. This package also had zero pre-existing programs (notypecheckscript at all), so there is no program a dep could be laundered through — the same clean caseservice-clusterreported.Numbers stated: before 59/78 packages, 120 programs, 293 pairs, 19 clean; after 60/78, 121, 302, 18 clean — +1 package, +1 program, +9 pairs (one per dep), this entry and nothing else.
Why the entry and not
paths, measured: redirecting the 9 deps to source takes this package's test layer from 0 errors to 648 (647TS6059"not under rootDir" + 1TS6133) — all 647 of the TS6059 land in another package's source, zero in this package's ownsrc/:packages/spec/src/**379,packages/core/src/**62,packages/plugins/plugin-security/src/**60,packages/objectql/src/**49,packages/services/service-messaging/src/**41,packages/metadata-core/src/**29,packages/formula/src/**15,packages/services/service-job/src/**6,packages/drivers/driver-sql/src/**6. Billed to packages that cannot pay them down — the sameservice-cluster(#14181: 0 → 435) and PR #12570 finding, reproduced at a larger scale because this package pulls more workspace deps.Gates
All measured figures in this section are the post-merge re-run on head
c6d25b73(merge commit8aff199c, merge base919beca43); the pre-merge readings they replace were taken at6a703bf42d, and the merge-round comment on this PR records both sets side by side.Package-level, on the merged head
c6d25b73:pnpm --filter @objectstack/service-automation typecheck— exit 0:check:test-typecheck: OK — @objectstack/service-automation's test layer compiles under packages/services/service-automation/tsconfig.test.json; 0 file(s) / 0 error(s).pnpm --filter @objectstack/service-automation test— exit 0: 103 test files / 1225 tests passed.pnpm check:type-check-coverage— exit 0:check-type-check-coverage: OK — 74/79 workspace packages type-checked (plus the root), 5 in the DEBT ledger (104 frozen raw errors), 1 exempt.pnpm check:type-source-resolution— exit 0 after the re-baseline:check-type-source-resolution OK — 121 tsc program(s) across 78 packages scanned; 60 registered as still resolving a workspace dep's types through dist/.pnpm check:nul-bytes— exit 0.Dispatch-derived gate list (
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, re-derived against the post-merge diff, final headc6d25b73), each exit code captured by redirect-then-read, never across a pipe: 64 commands — 62 exit 0, 2 exit 3 (NOT MEASURED), 0 red.NOT MEASURED, quoting each gate's own verdict:
check:dual-build-cjs-loads— exit 3: "PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/. … Runpnpm buildfirst. ⛔ This is NOT a pass: nothing was measured."check:type-check-debt— exit 3: "--re-measure cannot run: 13 workspace dependenc(ies) of the ledgered packages have no built type entry point on disk. … ⛔ This is NOT a pass and NOT a finding: nothing was measured."Both read the same missing prerequisite — a full-workspace
pnpm build, which is CI's job, not a per-package build closure. Three commands (check:pm-dispatch-gates,check:query-options-erasure,check:slot-lookup) needed longer than a 90s probe budget and passed on a second, unhurried run — each does a real full-tree scan, not a hang.Both edited gate scripts' own
--self-testare in that union and hold.Declined, with reasons
packages/services/*packages with the same gap — not touched.service-storagestill lacks atypecheckscript (DEBT entry 51);service-knowledgehas since graduated onmain(tooling(services):service-knowledgehas notypecheckscript — its test layer is compiled by no tsc program (#14062 family, sibling of #14181) #15049). The family-per-card pattern is deliberate (tooling(services):service-automationhas notypecheckscript — its test layer is compiled by no tsc program (#14062 family, sibling of #14181) #15048 is one of three siblings dispatched from [finding] No plugin package has a tsc program that compiles its tests — plugin-approvals alone hides 345 type errors, and 0 of 14 are in the test-typecheck ledger #14062).pathsrules added — measured at +648 (647 TS6059 + 1 TS6133) in other packages' source (above).@ts-expect-error/@ts-ignoreadded;strictuntouched.packages/specnot touched (single-owner lane).content/docs/releasesedit.Changeset
.changeset/service-automation-test-tsc-program.md,patchon@objectstack/service-automation.src/**is otherwise byte-identical (only the three private-read call sites in one test file changed, same assertions), so no shipped behaviour moves; the level reflects the publishedpackage.jsongainingtypecheck/check:test-typecheckscripts and atsxdevDependency.🤖 Generated with Claude Code
https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
Generated by Claude Code