Repository navigation
build(scenarios): a minimal unpublished build, and a narrow ./score entry that reads no objectql or plugin-sharing - #30938
objectstack-fleet[bot] wants to merge 6 commits into
Conversation
…re entry @objectstack/scenarios exported .ts sources only, so a consumer that links the framework tree and bundles its own entry with tsup (which leaves the dependency external) could not load ./score under plain Node: ERR_MODULE_NOT_FOUND on the .js specifiers, ESM and CJS alike. - tsup builds dist/ (ESM .js, CJS .cjs, .d.ts/.d.cts) per export subpath; the package stays private and unpublished, and the suites and run-scenarios keep reading src/. - ./score is now the narrow entry (src/score/narrow.ts, re-exports only): graph-shape scorer, naming, operation and run graders. Its import graph reads @objectstack/core and @objectstack/spec, never objectql or plugin-sharing. ./score/full is the previous whole entry (src/score/index.ts, unchanged code). - turbo runs the package's own build before its test, which now includes a tsup-built consumer loaded by plain Node with a resolve recorder. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
…e.at Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
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): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5de6f21f1de3d31ee9f7c0fa0d5bdacb9ba2173f && git checkout 5de6f21f1de3d31ee9f7c0fa0d5bdacb9ba2173f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 702570a3381412eb2eaacccabb37d50fb1b50dae && git checkout -B drift-repro 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 && git merge --no-ff 702570a3381412eb2eaacccabb37d50fb1b50dae
node scripts/docs-audit/affected-docs.mjs --json 6ddf827236902c0ccaee56b65431a4c8a9c7ac09
|
|
domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw 席位核对 · ACCEPT · #30915 · 2026-11-06T12:50ZHead-sha:
|
…OS_SKIP_DTS build passes it Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
|
domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw 席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T13:20ZHead-sha:
|
…t to stdout at exit Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
|
domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw 席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T13:31ZHead-sha:
|
…-cin84b # Conflicts: # packages/qa/scenarios/package.json
|
domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw 席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T14:06ZHead-sha:
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 42236202793 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Requested by Elon · project thread
domain:devx#1 · os-elon-musk · session_016WV4cwgUKpQgCE3UWsA74d
Fixes #30915
Clause-②: no
Metadata-protocol: none
维护者速读
@objectstack/scenarios加了一个不发布的最小 tsup 构建(dist/下 ESM + CJS +.d.ts),四个导出子路径全部指向构建产物;./score改为窄入口,只含图形打分与答题/写操作评分,不再牵出objectql和plugin-sharing;原先的完整入口改名为./score/full。.ts源码,cloud 打包后用纯 Node 加载会报 ERR_MODULE_NOT_FOUND;内联打包又等于把源码复制进 cloud(2.87 MB → 3.95 MB),违反裁决。run-scenarios仍直接读src/,行为零改动。唯一外部消费者是 cloud#3604(尚未落地)。回滚即 revert。packages/qa/scenarios/package.json的exports(./score与./score/full的分工);②src/score/narrow.ts(只做 re-export,没有搬文件);③turbo.json一行:本包test改为先跑本包build。pnpm --filter @objectstack/scenarios build && pnpm --filter @objectstack/scenarios exec vitest run test/build,预期 5 个测试全绿。What changes
@objectstack/scenarios(packages/qa/scenarios) exported.tssources only. A consumer that links the framework tree and bundles its own entry with tsup leaves the dependency external, so plain Node then loadssrc/score/index.ts, whose.jsspecifiers only a TypeScript resolver follows:ERR_MODULE_NOT_FOUND, ESM and CJS alike (measured by the cloud#3604 dev; reproduced here, see the ablation below).tsup.config.tsbuilds one entry per export subpath todist/(ESM.js, CJS.cjs,.d.ts/.d.cts,splitting: false, dependencies external), usingtsconfig.build.json(rootDir: src).buildends withcheck-dts-emitted.mjs(8/8 declarations present). Everyexportssubpath (.,./score,./score/full,./runner) now hasimport/requireconditions on the built files, wired the waypackages/lintis (atype: modulemulti-entry tsup package; no private package underpackages/had a tsup build to copy). The suites andrun-scenarios(tsx src/runner/cli.ts) importsrc/relatively and are untouched; no in-repo package imports@objectstack/scenariosby specifier../scoreentry.src/score/narrow.tsre-exportsscenario-graph,scenario-naming,scenario-operation-grade,scenario-run-gradeandscenario-score(soscoreGraphShape,artifactToEvalGraph,gradeRun,gradePersonaRun,gradeOperation, …). Its import graph reads@objectstack/coreand@objectstack/speconly. The previous whole entry,src/score/index.ts, is unchanged code and is now./score/full: it adds the capability-tag checks (scenario-tags.ts, which read@objectstack/objectqland@objectstack/plugin-sharing) and the card-levelscoreCardArtifact/gradeCardOperation/gradeCardAnswer. No score module moved, so Scenario grading: an overstep refused on read, an agent that pre-validates, and a plain decline all grade as failures; cards with persona scope lack the row-scope tag #30883 (editing score behaviour insrc/score/**) does not collide.turbo.json:@objectstack/scenarios#testdepends onbuild(was^build), so the package's owndist/exists before its suite runs;turbo run test --filter=@objectstack/scenarios --dry=jsonlists@objectstack/scenarios#buildas the test's dependency. Anyturbo run build/pnpm build(the root script) now builds the package, which is how a pinned framework tree is built.docker/Dockerfilein this repo installs published packages and builds no workspace package, so it needs nothing.READMEs (
packages/qa/scenarios/README.md,docs/qa/scenarios/README.md) and theindex.tsheader name the two entries.Tests
test/build/built-consumer.test.ts: a throwaway package that depends on@objectstack/scenarios, importsscoreGraphShapestatically andimport()s@objectstack/scenarios/score, is built with the repo's tsup (--format esm,cjs). The test asserts the bundle keeps the specifier external and does not carry the scorer, then loadsdist/index.jsanddist/index.cjswith plainnode. A preloadedmodule.registerHooksresolve recorder lists every URL the child resolves: the scorer loads frompackages/qa/scenarios/dist/, nothing fromsrc/, nothing matchingobjectqlorplugin-sharing, and (control)@objectstack/coreis seen.test/build/narrow-score-graph.test.ts: walks the source import graph fromsrc/score/narrow.ts(type-only imports included) and asserts no@objectstack/objectql/@objectstack/plugin-sharingspecifier, and the exact@objectstack/*set it reads. Control: the same walker fromsrc/score/index.tsfinds both.Acceptance notes
./scoreno longer exportsscoreCardArtifact, thescenario-tagsexports,gradeCardOperationorgradeCardAnswer; they are under./score/full. The card's acceptance requires./score's graph to exclude objectql and plugin-sharing, and the two card-level graders live inindex.tsbesidescoreCardArtifact, so keeping them in./scorewould have meant moving code out ofindex.ts, which the claim's serial constraint with Scenario grading: an overstep refused on read, an agent that pre-validates, and a plain decline all grade as failures; cards with persona scope lack the row-scope tag #30883 rules out. Its only out-of-repo consumer, cloud#3604, readsscoreGraphShapeand the run grader, both in./score.skip-changeset: the package is private (the dispatch order's fast lane). Measured: the Check Changeset job (.github/workflows/pr-automation.yml) exempts on the label alone and has no private-package branch, so nothing there asks a private package with a build for a changeset. Earlier PRs on this package did carry'@objectstack/scenarios': patchchangesets (.changeset/30289-…,30291-…,30292-…);.changeset/config.jsonhasprivatePackages: { version: true, tag: false }, so a changeset would only bump the private version..d.tsand a.d.ctsper entry, the simplepackages/lintpattern, notpackages/core's single-declaration pass. The runner exports classes, but no consumer reaches this package through both resolution modes today.Verification
All at
e748dfb0a0, the final head (origin/main26c965cb8fmerged, which brought #30846's loader change).pnpm --filter @objectstack/scenarios build: exit 0,check-dts-emitted: @objectstack/scenarios - 8/8 declared declaration file(s) present.pnpm --filter @objectstack/scenarios test:Test Files 20 passed (20),Tests 256 passed (256).typecheck: exit 0.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(exit 0) derived 65 commands; all 65 ran, every one exit 0.pnpm check:dual-build-cjs-loadsfirst exited 3 (PREREQUISITE NOT MET, no dist for 61 packages) and exited 0 after a whole-treeturbo run build(119/119 tasks).dispatch-gates.mjs --ran: exit 0, "65 derived famil(ies) accounted for — 65 run, 0 NOT-MEASURED".Ablation 1: the pre-fix export (`./score` import condition back on src/score/index.ts)
node scripts/ablation-replace.mjs --file packages/qa/scenarios/package.json --anchor '"default": "./dist/score.js"' --replacement '"default": "./src/score/index.ts"' -- … vitest run test/build/built-consumer.test.ts: mutation landed (anchor 1 → 0, blob 144f294e → 0d0da83a). Both plain-Node legs red with the card's error,Error [ERR_MODULE_NOT_FOUND]: Cannot find module '…/packages/qa/scenarios/src/schema.js' imported from …/src/score/index.ts. Restored: blob == HEAD,git diff HEADempty.Ablation 2: the narrow entry re-exports scenario-tags
ablation-replace.mjs --file packages/qa/scenarios/src/score/narrow.ts --anchor "export * from './scenario-graph.js';" --replacement "export { artifactToEvalGraph } from './scenario-graph.js';\nexport * from './scenario-tags.js';"thenpnpm build:ablation-dist-preflight.mjs @objectstack/scenarios "@objectstack/plugin-sharing"→ marker live in dist.vitest run test/build: 3 failed | 2 passed (the source-graph leg and both plain-Node legs red; the full-entry control and the external-bundle check stay green). Restored: blob == HEAD,git diff HEADempty; rebuilt,grep -c 'plugin-sharing\|objectql'ondist/score.js,dist/score.cjs,dist/score.d.ts= 0 each, andtest/build5/5 green.65 gates, exit codes at e748dfb
🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
Generated by Claude Code