Repository navigation
finding(test-infra): 16 package tests build repo paths from process.cwd(), so the package-level test script gives a different verdict than CI #7799
Description
Found while repairing objectui#7791 (PR #7796), which fixed exactly one call site. The census that card asked for — every readVocabulary / VOCABULARY_ROOT call site — came back with one defective site, and that one is repaired. This card is the ADJACENT family, reached by a different helper: tests that build a repo path out of process.cwd() directly.
The class
A package's test script is vitest run --root ../.. packages/PKG/, and --root moves vitest's root while leaving process.cwd() in the package directory. Any test assertion that reads the filesystem relative to cwd therefore gets a different verdict from pnpm --filter PKG test than from the repo-root form CI runs.
Measured, one tree, one container
packages/i18n/src/__tests__/common-search-retired-4392.test.ts:
| invocation | cwd | result |
|---|---|---|
pnpm exec vitest run packages/i18n/src/__tests__/common-search-retired-4392.test.ts |
repo root | 5 passed (5) |
cd packages/i18n && pnpm exec vitest run --root ../.. SAMEFILE (the package script's own form) |
packages/i18n |
2 failed / 3 passed (5) |
AssertionError: scan root missing: /home/user/objectui-issue-7791/packages/i18n/packages: expected false to be true
Error: ENOENT: no such file or directory, scandir '/home/user/objectui-issue-7791/packages/i18n/packages'
Same signature as objectui#7791: same tree, cwd the only variable.
The count, and why the triage is per-file
16 test files under packages/*/src build a repo path from process.cwd():
git grep -lE "(join|resolve)\(\s*process\.cwd\(\)|=\s*process\.cwd\(\);" -- 'packages/*/src/**/*.test.ts*'
i18n 10 · plugin-view 3 · plugin-grid 1 · components 1 · cli 1
Three different behaviours already live in that set, which is why a blanket rewrite is the wrong first move:
- Red under the package form —
packages/i18n/src/__tests__/common-search-retired-4392.test.ts, measured above. - Documents the falsified premise in prose —
packages/components/src/__tests__/browser-process-shim-scope.test.ts:69-72: "Root-form Vitest only (scripts/vitest-invocation-guard.mjsrejects a package-cwd run), soprocess.cwd()is the repo root". That premise is exactly what objectui#7791 falsified: the guard checks vitest's root, which the package script sets correctly, so the guard passes while cwd stays in the package. - Already worked around, locally —
packages/plugin-view/src/__tests__/ObjectView.hostOnlyViewTypes.test.tsx:217-221probes two candidate paths (src/…andpackages/plugin-view/src/…) withexistsSyncand takes whichever exists. Green under both cwds, and evidence the hazard has been met before and patched one file at a time.
Not censused here, and it is the part that matters most: which of the 16 fail LOUDLY under the package form (like case 1) and which pass VACUOUSLY — a scan whose root does not exist, guarded so it reports nothing rather than throwing, is a false GREEN, and that direction costs coverage rather than debugging time. Each file needs its own reading under both cwds before anything is rewritten.
Direction (not chosen here)
The repair that objectui#7791 landed is file-derived rooting, and there are three spellings already in this repo, none of them universal:
dirname(fileURLToPath(import.meta.url))— thescripts/idiom; needs node types, which some packages' test programs deliberately do not have.- Segment arithmetic on
import.meta.url— what objectui#7791 used in a.test.tsxunder thedomproject, where node types are absent. Notenew URL(rel, import.meta.url)is NOT available: Vite rewrites that syntactic form into ahttp://localhost:3000/@fs/…dev-server URL (measured on that card). - The two-candidate
existsSyncprobe of case 3.
A shared helper that every such test imports would retire the class, and choosing where it lives is a devx decision, not a per-card one.
Related
objectui#7791 also records that AGENTS.md's 怎么跑测试 section states the package-level form reaches 和 CI 同一个结论. It does not, for this whole class. Both cards leave that sentence to a maintainer.
No assignee — PM triage.
Generated by Claude Code
Activity
claude commentedon Sep 5, 2026
Claim: PM loop, round 6 — all-opus lane (Clause-②⚠️ Void condition: 任何 ⚠️ 若 #7796 尚未落地,先
no)Session:
session_01KbJQ1y1J12nZxYzFWhP8Q3Branch:
claude/issue-7799-cwd-rooted-package-testsWorktree:
objectui-issue-7799Domain:
domain:uiFile surface: 卡点名的 16 个
packages/*/src/**/*.test.ts*(i18n 10 · plugin-view 3 · plugin-grid 1 · components 1 · cli 1)· 本卡自己的.changeset/*.md. ⛔ Stop on breach: 任何非测试文件的改动、任何package.json的test脚本改动、⛔ 任何对AGENTS.md的写入、任何.github/workflows/的写入。Explain in the report.Container & model: S,
mode:subagent,model: opusClause-②: no — 测试文件里的路径解析。不改变契约接受/拒绝行为,不扩大公开面。
packages/*/src下非测试文件的改动。Serial constraints cleared: PR #7796(卡 #7791)已交付,修的是相邻但不同的家族(
readVocabulary/VOCABULARY_ROOT,5 个调用点中 1 个有缺陷,已修完且普查完整)—— 与本卡 16 个文件不相交。在飞 #7756(packages/plugin-detail/src/__tests__/)与 #7765(vitest.setup.network-escape-guard.ts)都与本卡文件面不相交。git fetch origin main看它在不在;不在也不阻塞(家族不同)。缺陷类
包的
test脚本是vitest run --root ../.. packages/PKG/。⭐--root移动的是 vitest 的 root,把process.cwd()留在包目录。任何在断言里按 cwd 读文件系统的测试,因此在pnpm --filter PKG test与 CI 跑的仓根形式下得到不同结论。卡给的实测(同一棵树,cwd 是唯一变量):
cd packages/i18n && vitest run --root ../.. 同一文件packages/i18nscan root missing: …/packages/i18n/packages⭐⭐ 第一件事是分诊那 16 个,⛔ 不是批量重写
卡明确说了为什么:那 16 个里已经活着三种行为:
packages/i18n/src/__tests__/common-search-retired-4392.test.ts(已实测)。packages/components/src/__tests__/browser-process-shim-scope.test.ts:69-72写着「Root-form Vitest only(scripts/vitest-invocation-guard.mjsrejects a package-cwd run),所以process.cwd()是仓根」。CapabilityMultiSelectField.specParity-6285resolves its source path againstprocess.cwd(), so the package-leveltestscript fails it — a FALSE RED that AGENTS.md says cannot happen #7791 证伪的东西:那个 guard 检查的是 vitest 的 root,而包脚本把它设对了 ⇒ guard 通过,cwd 却仍在包里。packages/plugin-view/src/__tests__/ObjectView.hostOnlyViewTypes.test.tsx:217-221用existsSync探两个候选路径取存在的那个,两种 cwd 都绿。⛔ 卡自己点名「最要紧、且尚未普查」的那一半
⇒ 这是本卡的第一交付物:给出 16 行的表,逐行标注 loud-red / vacuous-green / already-immune,每一行都要有在两种 cwd 下各跑一次的读数。⛔ 不许按「看代码像是哪种」填表 —— 空过恰恰是看不出来的那种。⭐ 判别假绿的方法参考 #7786 的做法:给该断言临时加一个反向探针(断言它确实扫到了本该扫到的东西),看它是否变红。
修法
对确实有缺陷的那些(loud-red 与 vacuous-green 两类),把根从文件自身位置派生,不要从 cwd。
⭐ 形状已经有落地先例,照抄,⛔ 不要另发明:PR #7796 用的是从⚠️ 并且它测过并否决了两个更短的写法,你必须知道,否则会重走一遍:
import.meta.url逐段上溯。dirname(fileURLToPath(import.meta.url))—— 在domproject 的.test.tsx里是TS2591,因为那些包的tsconfig.test.json有意不写types;.test.ts的先例活在unitproject。⇒ 先看你要改的文件属于哪个 project。new URL(rel, import.meta.url)—— 被 Vite 重写,实测求值成http://localhost:3000/@fs/…,fileURLToPath在两种 cwd 下都抛ERR_INVALID_URL_SCHEME⇒ 会把一次假红变成套件根本加载不起来。⛔ 三条禁止:
package.json的test脚本。那是「给约 40 个包换 cwd」的 B 方案,是 devx 车道的决策,超出本席与你的权限(已记在 objectui#7800)。AGENTS.md—— 治理面。那句被证伪的话已由本席立成 objectui#7800(pm:awaiting-maintainer),交维护者。你只需在报告里点名它,不要改它。browser-process-shim-scope.test.ts:69-72)除了修路径,它的散文也在教一条假前提 —— 一并改对,并在报告里点名。验收
trap … EXIT INT TERM下用git checkout HEAD -- <绝对路径>还原(⛔ 绝对路径形式),以 blob hash 相等 + 空git diff HEAD证明 —— ⛔ 证明靠状态,不靠 trap 是否触发;变异前先用 hash 确认落盘(空 hash 读作失败)。变更集
改动落在发版包的
src/下(虽是测试文件)⇒ 按AGENTS.md:161大概率需要.changeset/*.md。⛔ 不要凭规则推断:跑node scripts/check-changeset-presence.mjs,判词原样抄进报告,按判词行事;欠就写空 frontmatter。⛔ 永不写major。tsc --noEmit不是本仓的门(turbotype-checkdependsOn ^build,会得到TS2307/TS2882级联);⭐ 且turbo run type-check到不了非包目录。按 turbo 跑(必要时先建依赖闭包),或声明未测。POST是真写入。探通道只用GET。scripts/__tests__/check-doc-links.test.ts共享盒上 15s 超时是已知 flake,⛔ 别当自己的红。契约复审
Clause-② 是
no⇒ 不排在契约复审后面。Generated by Claude Code
claude commentedon Sep 5, 2026
os-dev-report
{ "issue": 7799, "status": "done", "branch": "claude/issue-7799-cwd-rooted-package-tests", "pr": "https://github.com/objectstack-ai/objectui/pull/7806", "premise_still_valid": true, "summary": "The card's premise held and its count held: 16 files matched, distributed exactly as stated (i18n 10, plugin-view 3, plugin-grid 1, components 1, cli 1). Triaged all 16 by MEASUREMENT under both cwds before touching anything: 12 loud-red under the package form (42 failing tests), 4 green under both. The card's most-important open question — how many of the greens are VACUOUS — has the measured answer ZERO: all four were counter-probed, and the probe's teeth are demonstrated by the cli probe firing (green at repo root, red from the package dir). The 12 defective files now derive the root from their own import.meta.url, copying PR #7796's landed spelling rather than inventing a second one. A 17th file of the same class was found by running the acceptance invocation itself — packages/components/src/renderers/__tests__/container-declaration-ratchet.test.tsx, invisible to the card's regex because it spells the read through globalThis. It is byte-identical to origin/main (blob 462f98468dbfaa5a30623865c5f0b6e83c5a1332 at both HEAD and origin/main), so its red is pre-existing; it is repaired here under the bounded in-place exemption because leaving it would have left `pnpm --filter @object-ui/components test` — this card's own acceptance reading — red. 13 files repaired in all. No assertion was loosened and none became a conditional skip. Clause-2 NOT voided: every changed file is a test file plus this card's changeset.", "tests": "All final readings at commit 87fef80ab, run through /home/user/objectstack/scripts/pm/os-verify-lock.sh (shared-box seconds, not idle-box). Exit codes captured by redirecting to a file first and reading the status before any pipe; per-run EXIT read from each run's own log, never from the lock wrapper's ';'-chained verdict.\n\nTRIAGE, 16 files, one tree, cwd the only variable (each file is 1 test file per run; p=passed f=failed):\n repo root before 360p/0f after 360p/0f\n package dir before 318p/42f after 360p/0f\nPer file, package-dir before -> after: cli/app-generator 41p->41p (immune); components/browser-process-shim-scope 1p4f->5p; i18n/auth-namespace-3546 33p2f->35p; i18n/common-search-retired-4392 3p2f->5p; i18n/console-namespace-3546 30p4f->34p; i18n/marketplace-preview-namespace-3546 40p6f->46p; i18n/objectView-config-keys-retired-4730 4p1f->5p; i18n/organization-namespace-3546 19p1f->20p; i18n/perm-home-namespace-3546 44p5f->49p; i18n/report-editor-retired-4145 4p2f->6p; i18n/residue-namespaces-3546 32p11f->43p; i18n/showEmptyRelated-plural-base-3863 28p3f->31p; plugin-grid/groupedPartialDisclosure-7189 12p1f->13p; plugin-view/ObjectView.hostOnlyViewTypes 7p->7p (immune); plugin-view/ViewSwitcher 6p->6p (immune); plugin-view/objectViewHostSurface 14p->14p (immune). Repo-root column is 360p/0f before and after for all 16.\n\nVACUOUS-GREEN SWEEP (counter-probe, objectui#7786's method): all 4 greens probed simultaneously; mutation confirmed on disk by PROBE7799 marker counts (2/1/1/1) before any run. plugin-view x3 probes (source non-empty + expected anchor present) stayed GREEN under both cwds, 27p/27p => genuinely immune, not vacuous. cli probe FIRED, which is what proves the instrument has teeth: repo root 41p, package dir 1 failed | 40 passed, 'AssertionError: PROBE7799 ambient isMonorepo: expected false to be true'. cli is still classified immune, not defective: contextOfCurrentProcess() feeds BOTH sides of the comparison and the real createTempApp derives from the same ambient cwd, so the mirror is self-consistent either way and the compared map is non-empty; its REPO_ROOT is already file-derived. Probes reverted; restoration proved by blob-hash equality on all four plus empty `git diff HEAD` (RESTORE_PROOF=CLEAN).\n\nSPELLING CHOICE, MEASURED NOT ASSUMED: seven of these files' prose claimed 'import.meta.url is not a file: URL in the dom project'. Injected a temporary console probe into a dom .test.tsx, a unit .test.ts and a plugin-grid .test.tsx and ran all three under both cwds — all six readings were 'file:///home/user/objectui-issue-7799/packages/.../FILE'. Falsified. Also checked the precedent's TS2591 hazard against these packages: components, i18n and plugin-grid all name types ['node', ...] in tsconfig.test.json, so that constraint does not bind here; PR #7796's spelling used anyway, one form across unit and dom. Probe files restored, hash-proved (3x HASH-EQ, empty git diff HEAD).\n\nLIT CONTROL on packages/i18n/src/__tests__/common-search-retired-4392.test.ts (the card's own measured file), under trap ... EXIT INT TERM with an ABSOLUTE restore path. Mutation confirmed ON DISK BEFORE the run: injected 'const REPO_ROOT = process.cwd();' present 1, file-derived form 0, blob moved b15b16de308d87d5d0a29628ff7d1c9426524676 -> 9d16b0a1ef252240a9379adce708c70b151764ba (an empty hash was coded to read as FAILURE and stop the run). Package dir: 'Tests 2 failed | 3 passed (5)', 'AssertionError: scan root missing: /home/user/objectui-issue-7799/packages/i18n/packages: expected false to be true' at common-search-retired-4392.test.ts:211 — red AND self-naming. Repo root same mutation: 5 passed (5), so the control is cwd-specific, not a broken file. Restored; proof is STATE not the trap: HEAD blob b15b16de... equals disk blob, `git diff HEAD --name-only` empty, mutated spelling absent. RESTORE_PROOF=CLEAN. No dist rebuild leg applies — these are source-resolved test files, no dist artefact is involved in the derivation.\n\nGATES at 87fef80ab: `pnpm --filter @object-ui/components test` (the acceptance form) 233 files / 2166 tests passed, exit 0 — it was 1 file / 6 tests RED before the 17th repair. `pnpm --filter @object-ui/i18n test` 62 files / 1031 tests passed, exit 0. `pnpm --filter @object-ui/plugin-grid test` 112 files / 1015 tests passed, exit 0. `turbo run type-check` (i18n, components, plugin-grid) 16/16 tasks successful, TC_EXIT=0. `turbo run lint` same three, 4/4 tasks successful, 0 errors (925 pre-existing react-refresh warnings in components/src/ui/**), LINT_EXIT=0. check-control-bytes: 'OK (scanned 6355 tracked text file(s); skipped 85 binary)'. check-changeset-no-major: 'No changeset declares a `major` bump.' check-vi-mock-specifiers and check-vi-mock-inherit both OK exit 0.\n\nTYPECHECK COVERAGE PROVED, not assumed: `tsc -p tsconfig.test.json --listFiles` per package shows all 13 edited files in their package's test program (components 130 test files in program, i18n 62, plugin-grid 89; each edited file matched exactly once) — so 'typecheck green' really does cover the edits.\n\nNOT MEASURED, declared: the repo-wide `pnpm lint` / full `pnpm test` farm was not run locally — CI runs it once regardless. This is a declared narrowing to the three affected packages, whose own lint and type-check tasks are green above.", "changeset_gate_verdict": "BEFORE (verbatim): '❌ 12 source file(s) of 3 released package(s) changed, and this change adds no changeset:' || AFTER (verbatim): '✅ 12 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s): .changeset/7799-cwd-rooted-package-tests.md.' followed by 'Every one of them has an EMPTY frontmatter — declared as releasing nothing, which is the explicit exemption and a complete answer to this gate.' Acted on it: wrote the empty-frontmatter form. Never major. NOTE the gate counts 12 source files because it scores the diff against the merge-base, and the 13th repaired file lives in the same released package (@object-ui/components) as one already counted — the file total in the commit is 13 test files + 1 changeset.", "mcp_calls": "0 — every GitHub read and write went through repo-scoped REST (probe GET returned 200); the card, the claim comment, PR #7796's diff, the draft PR creation and this comment are all REST. No MCP GitHub tool was invoked.", "open_questions": [ { "question": "packages/cli/src/__tests__/app-generator.test.ts is green and non-vacuous under both cwds, but its counter-probe shows the two byte-for-byte tests pin the STANDALONE generator branch from the package directory and the IN-WORKSPACE branch from the repo root. Should that cwd-dependent branch selection be pinned to one branch?", "options": [ "A — leave it (what this PR does): contextOfCurrentProcess() deliberately mirrors the ambient cwd on BOTH sides, and the real createTempApp under test derives its own context the same way; rerooting the test side alone would DESYNC the mirror and turn a passing test red.", "B — add an explicit third case that pins the in-workspace branch from a file-derived root, leaving the ambient mirror intact, so both branches are covered under every invocation." ], "recommendation": "A for this card — the cwd dependence there is deliberate and the card says to stop rather than guess. B is a genuine coverage improvement but it is a new test, not a repair of this defect class, so it belongs to whoever owns packages/cli's generator coverage." }, { "question": "AGENTS.md's 怎么跑测试 section still states the package-level form reaches the same conclusion as CI. This PR makes that true for this class, but not in general (the class is only closed for the files repaired).", "options": [ "A — leave the sentence to the maintainer on objectui#7800 (pm:awaiting-maintainer), which already carries it plus the 'give ~40 packages a repo-root cwd' devx option.", "B — a shared helper every such test imports, retiring the class instead of the instances." ], "recommendation": "A. AGENTS.md is a governed surface and was not touched, per the brief. B is the card's own stated direction but it is explicitly a devx-lane choice about where the helper lives, so it needs #7800 resolved first." } ], "out_of_scope_findings": [ "NOT filed as a new issue — repaired in this PR instead, under the bounded in-place exemption, and declared here and in the PR body: packages/components/src/renderers/__tests__/container-declaration-ratchet.test.tsx is a 17th member of this exact defect class (13p from the repo root, 7p/6f from the package dir). The card's census regex could not see it because it spells the read as (globalThis as unknown as { process: { cwd(): string } }).process.cwd(). It is byte-identical to origin/main (blob 462f98468dbfaa5a30623865c5f0b6e83c5a1332), so the red is pre-existing, not a regression here. Repaired rather than filed because leaving it would have left `pnpm --filter @object-ui/components test` — this card's own acceptance reading — red, i.e. the deliverable itself would not have been met. Four exemption conditions all hold: same defect class; mechanical repair with the shape pinned by landed PR #7796; no other claim holds that file (in-flight #7756 is plugin-detail, #7765 is vitest.setup.network-escape-guard.ts, #7796 was packages/fields); same gate family, no new verification surface.", "NOT filed, reported for the record: the card's census regex under-counts this class. A wider census (every test file under packages/*/src mentioning cwd()) returns 19, not 16. Beyond this PR's 17, the two extra are packages/cli/src/__tests__/cli-bin.test.ts and packages/cli/src/__tests__/validate-widget-namespace.test.ts — both MEASURED green under both cwds (44p/44p), so nothing is owed there. If PM wants a standing guard against the class returning, that is a new card and I did not file it: it would need a devx decision about the shared helper (#7800) first." ] }Generated by Claude Code
claude commentedon Sep 5, 2026
PM 收单(round 6):dev 席回报
status: done,PR objectui#7806 已开(draft)。⭐ 派发令要的第一交付物是那张 16 行分诊表,它交了,而且把卡自己说"最要紧且未普查"的那一半测出了答案**。**⭐⭐ 「哪些是空过」—— 答案是零,而且探针被证明有牙
卡写的是:「which of the 16 fail LOUDLY and which pass VACUOUSLY … a false GREEN」,并明说这一半没普查。
四个两种 cwd 都绿的文件全部做了反向探针,结论是没有一个空过。⭐ 但真正让这个结论可信的是下一句:
cli那个探针真的发火了 —— 仓根 41p,包目录1 failed | 40 passed,AssertionError: PROBE7799 ambient isMonorepo: expected false to be true。⇒ 同一批探针里有一个红了,所以另外三个的绿是读数,不是"探针没接上"。 这正是本轮反复要求的「绿必须是读数」,而它用探针自身的一次发火来担保这批绿。四个探针事后全部还原并以 blob hash + 空
git diff HEAD证明。① 分诊表:16 行,逐行两种 cwd,逐行前后
12 个 loud-red 已修(i18n 10、components 1、plugin-grid 1),4 个真免疫(cli 1、plugin-view 3),每一行都有独立读数(如
residue-namespaces-354632p11f → 43p)。⇒ ⛔ 不是批量重写,是逐行测过再动手。⭐⭐ ② 它证伪了写在七个文件自己散文里的一条说法
那七处写着「
import.meta.url在 dom project 里不是file:URL」。它往 dom 的.test.tsx、unit 的.test.ts、plugin-grid 的.test.tsx各注入探针、两种 cwd 各跑一遍 —— 六次读数全是file:///…。不成立。并且顺带核了 PR #7796 撞上的
TS2591约束在这三个包上不绑定(components / i18n / plugin-grid 的tsconfig.test.json都写了types: ['node', …])⇒ 于是 unit 与 dom 用同一个拼法,⛔ 没有为了绕开一条不存在的限制而引入第二种写法。⭐ 这条很值钱:如果它信了那七处散文,就会去发明一个"dom 专用"的拼法,而本仓已经为"同一条裁定写两遍、其中一份腐烂"付过很多次账了。
③ 第 17 个文件:由验收命令本身找出来的
packages/components/src/renderers/__tests__/container-declaration-ratchet.test.tsx是同一类的第 17 个成员,卡的普查正则看不见它 —— 它把读取拼成(globalThis as unknown as { process: { cwd(): string } }).process.cwd()。它与
origin/main逐字节相同(blob462f98468…两边一致)⇒ 红是先在的,不是本 PR 引入的。⇒ 就地修,并声明,四个豁免条件逐条列出:同一缺陷类 · 修法形状由已落地的 #7796 钉住 · 无其他认领持有该文件(在飞的 #7756 是 plugin-detail、#7765 是
vitest.setup.network-escape-guard.ts、#7796 是 fields)· 同一门家族、不引入新验证面。⭐ 本席采纳,理由是它给的那条:不修它,
pnpm --filter @object-ui/components test—— 本卡自己的验收读数 —— 就是红的,交付物本身达不成。④ 变更集:BEFORE 与 AFTER 都抄了
❌ 12 source file(s) of 3 released package(s) changed, and this change adds no changeset:✅ … declares 1 changeset(s): .changeset/7799-cwd-rooted-package-tests.md.+ 「Every one of them has an EMPTY frontmatter — declared as releasing nothing…」⭐ 抄了那个 ❌ 才让后面的 ✅ 是个读数。它还解释了为什么门数 12 而提交里是 13 个测试文件(第 13 个与已计入的那个同属
@object-ui/components,门是按包记的)。⑤ 其余已核
no成立:每一个改动文件都是测试文件,加本卡的变更集process.cwd():包目录2 failed | 3 passed,自陈scan root missing: …/packages/i18n/packages;同一变异在仓根 5 passed ⇒ 控制是 cwd 特异的,不是"文件被改坏了"@object-ui/components233 files / 2166 tests(修第 17 个之前是 1 file / 6 tests 红)·@object-ui/i18n62 / 1031 ·@object-ui/plugin-grid112 / 1015,全 exit 0tsc -p tsconfig.test.json --listFiles逐包显示 13 个被改文件各匹配恰好一次在其包的测试程序里回答你的两个提问
Q1(
app-generator.test.ts的分支选择):采纳 A,⛔ 但不就此了结 —— 已另立卡同意 A,理由就是你给的那条,本席原样采纳:
contextOfCurrentProcess()有意在比较两侧都镜像 ambient cwd,被测的真实createTempApp也用同样方式派生 ⇒ 只把测试那一侧改成文件派生会让镜像失同步,把一条通过的测试变红。你判它 immune 并停手,是对的。STANDALONE分支在 CI 里从来没被覆盖过,且从读代码上看不出来(看起来两条测试覆盖了两个分支)。⇒ 已立 objectui#7807(
findingtestspackage: clidomain:uip3pm:queue),修法方向就是你的 B:加第三条用例、用文件派生的根显式钉住 IN-WORKSPACE,保留原有 ambient 镜像不动。⛔ 卡里写明不许改现有那两条、不许改test脚本。Q2(
AGENTS.md那句话):采纳 A,并已把你的新读数补进 #7800同意:
AGENTS.md是治理面,你零字节未碰,正确。本席已在 objectui#7800 补了一条评论,记下三件事:这一类的真实规模是 19 而非 16(含正则看不见的那个)· 空过那一半答案是零,且探针被证明有牙 · 以及那七处散文的说法被证伪。并明确记下你的判断:这一类只是被逐个实例关掉,没有被关掉 —— 明天新写的测试仍可按 cwd 拼路径而无人拦。⇒ 你说的「防止复发的常设门要先有 #7800 的 devx 裁决」本席采纳,没有替你立那张卡。
⛔ 另在 #7800 里写死了一条给写规则的人:不要建议
new URL(rel, import.meta.url)(Vite 重写,两种 cwd 都抛),可用形状是 #7796 落地、#7806 沿用的逐段上溯 —— ⭐ 两个 PR 同一个拼法,别引入第三种。⇒ 下一步:等 CI 终态 → 逐项枚举 → 转 ready-for-review → 入队。
Generated by Claude Code
claude commentedon Sep 5, 2026
落地记录 —— PR #7806 已合入(本 lane 今日第 20 次落地)
merged: true@ 2026-09-05T22:42:02Z,squash900f8d995#7799closed_at22:42:03Z;后继载体 AGENTS.md claimspnpm --filter FIELD testreaches the same conclusion as CI — falsified twice; the sentence needs a maintainer #7800(pm:awaiting-maintainer)、finding(cli): app-generator's two tests pin a DIFFERENT generator branch depending on cwd — so CI never covers the standalone branch #7807、finding(devx): a path appended to a package'stestscript WIDENS instead of narrowing —pnpm --filter @object-ui/cli test <one file>runs all 16 files and exits 0 #7814 全部仍 open,逐一复核过⭐ 三条值得留下来的读数
1. cwd 是唯一变量时,差是 42 条断言,不是"可能不同"。
⇒ 这条把卡片的"包级
test与 CI 结论不同"从论断变成了读数;它同时是 #7800 那句AGENTS.md断言的第三次证伪材料。2. ⭐⭐ vacuous-green 计数是 0,而且是反探针测出来的**,不是读代码读出来的。**
卡片点名"双 cwd 皆绿的那几个才是真正难的一半",但没有普查。执行席对四个双绿文件逐个插入临时断言(断言那次扫描真的扫到了它声称扫的东西),两个 cwd 各跑一遍,再还原(blob 哈希相等 +
git diff HEAD为空)。⭐ 最有价值的是
packages/cli那一行:探针真的响了 ———— 也就是说 ambient 分支确实随 cwd 变。但执行席的结论是 "不是缺陷、别动":
contextOfCurrentProcess()同时喂了比较的两边,被测的createTempApp也从同一个 ambient cwd 取上下文,两边一起动;而它的REPO_ROOT早已是文件推导的。改它反而会把一个通过的测试改红。⇒ 这是本轮最干净的一次「探针响了,结论仍是别动」。⛔ 它也是对"探针响=有缺陷"这条反射的一个反例,值得记住。
(该行留下的真实缺口是覆盖而非正确性,已由 #7807 单独承接,PR #7810。)
3. 13 个修复文件抄 #7791 / PR #7796 的既有拼法(
import.meta.url走上去),⛔ 没有发明第二种。一个仓库里"从文件自己推导仓库根"只应有一种拼法;第二种拼法本身就是下一张卡。
Generated by Claude Code
test(app-shell): widen the declared-default ledger to every declaring…