fix(test): visibility-scope-delegates 基线红是 process.cwd() 导致走图器在空图上空转
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
## 现象
`apps/api/tests/capability/skill/visibility-scope-delegates.test.ts` 在 `origin/main` 上稳定红 5 条(实测 SHA `5c7c3f30e49a4f3d6cb91159996f1b1dfca56b9b`,`b1b44607f442a22c6b0afbf67f9517aeb6b68dea` 同)。这是**基线失败**,与任何在途 feature 无关(detached origin/main 复现)。
红的断言:
- ②「真实源码里没有那三个字段的比较」
- ③ 全部 4 条:一跳 / 距离=2 / 直接 import 反证 / 「走图器不是在空图上空转」
## 根因:`process.cwd()` 不是 `apps/api`
```ts
const SRC = join(process.cwd(), "src");
```
`vitest --root apps/api` 只改 vitest 的 root,**不会 chdir**。从仓库根跑时 `SRC` 指向 `/src`,该目录不存在:
```
-> src/domain/skill/visibility-scope.ts 存在? false
/apps/api -> 存在? true
```
后果分两路,恰好复现出报告里那 5 条:
1. ② 第一条 `readFileSync` 抛 ENOENT → 红。
2. `realGraph()` 里 `localImportsOf` 抛异常被 `catch` 吞成叶子 → 图只剩 `{SUBJECT: []}`,`graph.size === 1`。于是 ③ 的一跳 / 两跳 / 直接 import 反证 / 空图哨兵四条红;而两条纯合成图的反证(走满两跳、断边)因为不碰真实图**照样绿**。
**这正是「静态痕迹 ≠ 动态事实」的另一面:它不是真的红,是整个文件对真实源码空转。** 被测源码 `src/domain/skill/visibility-scope.ts` 目前**完全正确**——它确实委托了 `decideCapabilityVisibility`,`capability-listing.ts` 也确实 import 了 `permission-decision.ts`。门控红了,但红的原因跟它要守的不变量无关;反过来说,如果这文件当初就是这么写的,它从来没有真正守过 #459 那条裁决。
## 修法
`SRC` 从测试文件自身位置推导(`fileURLToPath(import.meta.url)`),不依赖 cwd。
并**加一条哨兵**:`SRC` 必须真的解析得到 `visibility-scope.ts`,否则直接红——避免 `realGraph()` 的 `catch` 再把「读不到文件」静默降级成空图。现有的 `graph.size > 2` 哨兵事后能发现,但它跟真实违规的红长得一样,分不清「门控坏了」和「代码违规了」。
范围核过:全仓 `apps/api/tests/` 下只有这一个文件用 `process.cwd()`。
## 验收
```bash
pnpm exec tsx .harness/scripts/with-test-isolation.ts -- npx vitest run --root apps/api tests/capability/skill/visibility-scope-delegates.test.ts
```
从**仓库根**跑,30 条全绿;并给出反证:把 `SRC` 改回 `process.cwd()` 那版,5 条依旧红(证明修的是这个)。
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with apps/api/tests/capability/skill/visibility-scope-delegates.test.ts and inspect how SRC and realGraph resolve the source files. Run the provided Vitest command from the repository root; done means all 30 tests pass, a missing source path fails explicitly, and reverting the path handling reproduces the five baseline failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100