Skip to content

test(cli): pin os serve config-boot for the authored shape #3887 reported - #4360

Merged
os-zhuang merged 4 commits into
mainfrom
claude/bare-definestack-startup-failure-673851
Jul 31, 2026
Merged

test(cli): pin os serve config-boot for the authored shape #3887 reported#4360
os-zhuang merged 4 commits into
mainfrom
claude/bare-definestack-startup-failure-673851

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

一句话

#3887 报的崩溃早已被 #4110(closes #4085)修好,但它报的那个形态从来没有被测试钉住。本 PR 补上那一次 boot,并顺带把 #3887 关掉。

事实核实(不是推断)

按 issue 里逐字的复现跑了一遍当前 main:

Loading objectstack.config.ts...
✓ Server is ready
Plugins: 29 loaded
         … com.objectstack.metadata, ObjectQL, cfgload, RestAPI, …

Service 'manifest' is async - use await 没有了,artifact read FAILED 也没有了(后者在 #4110 里被改成 ENOENT 时的正常 no compiled artifact at …)。

而且不止「没崩」——登录后对 cfg_note 做了真实读写,确认对象是真的在服务:

POST /api/v1/data/cfg_note  → {"id":"cfg_note-…","title":"hello 3887", …}
GET  /api/v1/data/cfg_note  → {"records":[…],"total":1}

#4110 没有 link #3887,所以它一直挂着 OPEN。

为什么还要加测试:现有的 pin 盖不住这个形态

serve-no-artifact.e2e.test.ts 已有 4 个 boot,但每一个 fixture 都是 plain object literal(export default { … }),没有一个走 defineStack()。这不是无谓的区别:

  • defineStackparse + normalize。同一份 config 经过它之后,每个 object 被盖上 datasource: 'default',每个 field 被补成完整 descriptor。literal fixture 原样进 boot,只有这个 fixture 是「spec 产出的样子」进 boot。
  • 这样的 fixture 只能放在真实 node_modules 解析得到的地方:@objectstack/spec 对 config bundler 是 external(BUNDLE_REQUIRE_EXTERNALS),所以它没法像其它三个那样待在 OS tmpdir 里。

第二点正是这个洞能活过修复的原因——不是没人想到,是放不进去。所以新 fixture 落在本包的 gitignored tmp/ 下,和用户工程一样经由真实 node_modules 解析。

这个断言是有承重的

把 fixture 的 manifest.id 改掉之后跑,测试变红,而 server 依然正常起来:

❯ test/serve-no-artifact.e2e.test.ts:207
    expect(stdout, `app plugin missing from the boot banner`).toMatch(/Plugins:[\s\S]*cfgload/)

也就是说它断言的是「app 真的注册并 start 了」,不是「banner 里有字」。

范围说明(写进文件了,避免后人读多)

这一 boot 钉的是这个形态的端到端(config 加载 → app 注册 → 无 dist/ 起服务),不是 fault 1 的机制。单独 revert CLI 侧的 append 已经复现不出崩溃了 —— ADR-0116(#4131)之后 plugin ordering 变成 declared、kernel-enforced 的契约(那个 commit 原话:「kernel.use() registration order proves nothing」,并且点名 AppPlugin/#4085 是标准例子)。两个保证都要,但钉在不同层。

验证

⚠️ 本机跑测时长抖动很大(同一文件 9.5s→478s):是本机另外六个 worktree 在并行跑 suite 造成的资源噪音,不是新测试的成本 —— 已确认无我这边遗留的 serve 进程,机器空闲时新测试单独跑 15.5s。

Closes #3887

🤖 Generated with Claude Code

os-zhuang and others added 2 commits July 31, 2026 16:07
#3887 filed `Service 'manifest' is async - use await` from a bare
`defineStack()` config with no `dist/objectstack.json`. #4110 fixed that
crash under #4085 and never linked #3887, which stayed open — and every
fixture pinning the fix is a plain object literal, so the shape the issue
actually reported was left unexercised.

That is not a cosmetic difference. `defineStack` parses and normalizes, so
an authored config reaches boot carrying defaults no literal in the file
writes: `datasource: 'default'` on every object, a full descriptor on every
field. And such a fixture only resolves where a real `node_modules` does —
`@objectstack/spec` is external to the config bundler
(BUNDLE_REQUIRE_EXTERNALS) — so it cannot live in the OS tmpdir beside the
others. That resolution constraint is why no test had ever booted an
authored config, and why the gap outlived the fix.

Verified against the issue's verbatim repro: boots, registers the app, and
serves reads/writes on `cfg_note` over REST. The new boot asserts the app
reaches the started plugin set and that a driver resolved behind the stamped
datasource; breaking the fixture's manifest id turns it red while the server
still starts, so the claim is the app's, not the banner's.

Scope stated in the file: this pins the authored shape end to end, not
fault 1's mechanism — ADR-0116 (#4131) made plugin ordering a declared,
kernel-enforced contract, so reverting the CLI-side append alone no longer
reproduces the crash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 31, 2026 9:11am

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@os-zhuang
os-zhuang merged commit fe0465c into main Jul 31, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/bare-definestack-startup-failure-673851 branch July 31, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

1 participant