Skip to content

build(tsconfig): split the shared base out of the root tsconfig (#26092 part 1) - #26203

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-jfhqg2
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-jfhqg2

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread
Part of #26092 (PR 1 of 2: the tsconfig half; the vitest preset follows as PR 2).

Clause-②: no
Metadata-protocol: none

What changes

  • tsconfig.base.json (new) holds the compiler options the root tsconfig.json used to carry, unchanged. The 72 package/app/example configs that extended the root now extend it.
  • Root tsconfig.json is now only the type-check program for scripts/ and the top-level configs: it extends the base, adds types: ["node"], keeps its exclude.
  • tsconfig.test.base.json (new) holds the vitest module semantics (noEmit, module: esnext, moduleResolution: bundler, lib: ["ES2022"]). 36 of the 42 tsconfig.test.json files now spell "extends": ["./tsconfig.json", "REL/tsconfig.test.base.json"] and keep only what differs (DOM in lib, types). The other 6 do not re-set module semantics this way and are untouched.
  • Module re-sets: the two configs that re-set NodeNext identically to the base (packages/adapters/hono, packages/qa/http-conformance) drop the duplicate; the seven ES2020/bundler configs keep it with a one-line reason (four drivers: no "type": "module", so NodeNext compiles their sources as CommonJS and refuses import.meta, TS1470 measured; embedder-openai / knowledge-memory / knowledge-ragflow: tsup-bundled, no "type": "module").
  • turbo.json globalDependencies gains both bases, so a change to either invalidates every cached build the way a change to the root did; .github/workflows/ci.yml core: filter lists both verbatim, which check-ci-filter-parity requires (measured: FAIL naming both files without these two lines).
  • Ledgers: the three empty test-typecheck-debt.json files (packages/rest, packages/client, packages/plugins/knowledge-ragflow) are deleted (check-test-typecheck.mts reads a missing ledger as empty); the graduation history inside the empty TEST_DEBT object is deleted, keeping the closed-ledger rule.
  • Comments: 63 mentions of "the root config" across 53 tsconfig comments now say "the base config".

No semantic change, measured

tsc --showConfig -p FILE for every non-ui tsconfig*.json (143 files), before (main 95294be) and after: 142 byte-identical, file lists included. The root differs by exactly types: ["node"]. Strictness is not loosened anywhere.

The card's premise on the root DEBT entry does not hold

Root program errors, tsc --noEmit -p tsconfig.json with the import closure built: 26 before, 26 after types: ["node"]. The TS2591/TS2584 pile the entry's note blamed on the missing Node types was already gone. What stands: scripts/analytics-reconcile imports @objectstack/* and example sources the root program cannot resolve (TS2307 x17, plus TS7006 x7 they cascade into), Object.hasOwn under lib ES2020 in scripts/check-test-typecheck.mts (TS2550), and an unused local in examples/app-showcase pulled in by import (TS6133). So the @objectstack/spec-monorepo DEBT entry stays at 26 and its note is rewritten to that composition (the stale compositionAt: 80 is dropped). Graduating it also needs a typecheck:root script and its step in .github/workflows/lint.yml: separate work, not in this PR. The card's acceptance line about deleting the entry is not met by design.

Landing

Tier H: .github/workflows/ci.yml is a governed surface, so this needs the maintainer's approval. The maintainer chose this shape (one PR carrying the two filter lines) on the thread decision card. Root ci.yml is also under a short hold for other in-flight work; land after that clears.

Verification (head 07de412)

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 117 commands on this head; all 117 ran, each exit captured before any pipe: 117 exit 0. --ran reconciliation: 117 derived, 117 run, 0 NOT-MEASURED, 0 UNRUN.
  • Earlier on this branch five of them first refused on prerequisites (exit 2/3: shallow clone, unbuilt dists); after git fetch --unshallow and a build of every non-ui package they ran and exited 0, and they are in the 117 above.
  • node scripts/check-ci-filter-parity.mjs: FAIL without the two ci.yml lines, exit 0 with them.
  • turbo run typecheck --force over rest, client, knowledge-ragflow (the three deleted ledgers, whose typecheck runs check:test-typecheck), core, driver-sql, hono, http-conformance, spec: 49/49 tasks successful (before the main merge; the merge touched no non-ui tsconfig).
  • Effective-config diff: see above. tsc -b was not used for the before/after count: the root config has no noEmit or outDir, so tsc -b would emit next to scripts/; the count is tsc --noEmit -p, which is what check:type-check-debt measures.
  • Changed lines: well under the 3000 human-merge threshold. No changeset: no published package ships a tsconfig, and every package's effective compiler configuration is unchanged (skip-changeset).

Acceptance notes

  • os create --in-repo (rootTsconfigExtends in packages/cli/src/commands/create.ts) still points new in-repo scaffolds at the root tsconfig.json, which is now the scripts program, so a new scaffold would inherit types: ["node"] and the root exclude. Not changed here (outside this card's file surface); the CLI tests pin the root path.
  • packages/drivers/driver-memory/tsconfig.json sets noUnusedLocals: false, a pre-existing loosening against the base; untouched.
  • embedder-openai, knowledge-memory, knowledge-ragflow type-check with 0 errors under NodeNext, so their bundler re-set could be dropped later; kept here to keep the change semantics-free.
  • The deleted packages/rest ledger's _note carried a re-derivation grep for any-typed response fixtures; it is in git history.

Generated by Claude Code

Packages, apps and examples now extend tsconfig.base.json; the root
tsconfig.json is the type-check program for scripts/ and the top-level
configs and declares types ["node"]. Test-layer configs extend
tsconfig.test.base.json for the vitest module semantics. Every package
config's effective configuration (tsc --showConfig, file lists included)
is byte-identical before and after.

Also deletes the three empty test-typecheck-debt.json ledgers and the
graduation history inside the empty TEST_DEBT object, and rewrites the
root DEBT note to the composition measured today (26, unchanged).

Claude-Session: https://claude.ai/code/session_01EaorEqkvnJBed5uX9BjSUG
Co-authored-by: Claude <noreply@anthropic.com>
Every package now extends tsconfig.base.json (and test configs
tsconfig.test.base.json), so turbo must invalidate on them the way it did
on the root tsconfig.json; ci.yml's core filter lists them verbatim, as
check-ci-filter-parity requires.

Claude-Session: https://claude.ai/code/session_01EaorEqkvnJBed5uX9BjSUG
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 89 changed file(s) yielded no anchor (packages/adapters/hono/tsconfig.json, packages/apps/account/tsconfig.json, packages/apps/setup/tsconfig.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 71 changed package(s)).

What this run could not see
  • 89 changed file(s) yielded no anchor (packages/adapters/hono/tsconfig.json, packages/apps/account/tsconfig.json, packages/apps/setup/tsconfig.json, …) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

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

@objectstack-fleet

objectstack-fleet Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · devx seat 2 · 2026-10-26T15:27Z

Seat domain:devx#2 (#20163) · session_01Q4MDXRbEJCNdPAP4SiXwp9 · reviewed head 07de412e3c · card #26092 PR 1 of 2 (Part of #26092), claim 6417141844. The maintainer picked option A on the thread's decision card: the PR carries the two ci.yml filter lines and the turbo.json globalDependencies entry, so it is Tier H (check-governed-merges --branch → governed, hit .github/workflows/ci.yml). ⛔ The seat neither approves nor merges it. It needs a GOVERNED_APPROVERS approval.

  • Scope, as the card's Wanted (PR 1) lists it:
    • New tsconfig.base.json and tsconfig.test.base.json. Packages extend the base, and the tsconfig.test.json files extend the test base.
    • The root tsconfig.json becomes the scripts/ program, extending the base, with types: ["node"].
    • The three empty ledgers and the empty TEST_DEBT block are deleted. The block's prose goes with the dead code it described, which the card asks for.
    • ci.yml (+2) and turbo.json (one line) add the two base files to the change filter and to Turbo's global inputs, so an edit to a base invalidates what it feeds.
    • 138 files, +254/−632. No ui/ path.
  • No loosening, measured: tsc --showConfig is byte-identical on 142 of 143 non-ui tsconfigs. The one that differs is the root, which gains types: ["node"].
  • Premise falsified, entry kept (accepted deviation): the card expected types: ["node"] to clear the root DEBT entry. Measured, it moves the count by zero (26 → 26), because the TS2591/TS2584 pile the old note blamed had already gone. The entry stays and its note is rewritten to the classes that do stand: 17 TS2307 and 7 TS7006 in the analytics-reconcile tree, TS2550 Object.hasOwn under ES2020, and TS6133 from an imported showcase source. The acceptance line "root DEBT entry gone" is unmet for that measured reason, not skipped.
  • Gates: 117 derived commands, all exit 0, with 0 NOT-MEASURED (os-dev report 6419765137). CI on this head was still running at review time.
  • Landing: ready + auto-merge once every check is green or skipped. [Edit: wrong for a Tier H diff. AGENTS.md Prime Directive 14 forbids an AI seat to ready, queue or arm auto-merge before a GOVERNED_APPROVERS approval. The seat armed it at 16:20Z by mistake, then disabled auto-merge and redrafted at 16:21Z. It was never queued.] The PR stays a draft until the approval, and then the owning seat lands it.
  • Out of scope: the seat files the report's two findings (os create --in-repo still points at the root tsconfig.json; graduating the root DEBT entry).

Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 40361692247 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test UI (12/16) — 失败步骤: Run the ui tests (shard 12/16)

    × has no on/off flag to rename to — `enable` is a capabilities object, not a boolean 8ms
    FAIL   unit  packages/app-shell/src/services/MetadataService.retiredObjectEnabled.test.ts > objectui#6238 · the schema oracle — both tombstone keys are refused BY NAME > has no on/off flag to rename t
      ↳ 失败原因: AssertionError: expected 48 to be 47 // Object.is equality
    
  • Test UI (7/16) — 失败步骤: Run the ui tests (shard 7/16)

    × has no near-spelling for any of them — unlike objectui#6041, nothing here is a rename 6ms
    FAIL   unit  packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts > the instrument > has no near-spelling for any of them — unlike objectui#6041, nothing here is a rename
      ↳ 失败原因: AssertionError: expected 48 to be 47 // Object.is equality
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 26 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

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

Labels

ci/cd size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants