Repository navigation
Commit ad06144
chore(ci): census the call sites that set the vouched-reference mark (#31086)
security#1 · os-tesla · session_01L9qibvynRbCtMndW8EHNGc
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:新增门禁 `check:vouch-for-reference-callers`:在
`packages/`、`examples/`、`apps/` 下,只有 file-attachments
写入方(`file-attachment-service.ts`,恰 2 处直接调用)可以设置 vouched-reference 标记;对
`vouchForReference`、`VOUCHED_REFERENCES` 或其 Symbol
描述的任何其它写法(改名、命名空间、别名、`.call`、方括号、`defineProperty`、看不懂的 `Symbol.for`
参数)都转红并点名文件与行。
- **为什么改**:该标记是一项受控豁免,每个调用点都须单独复核;门禁把这条规则变成机械检查,新调用点只能以显式的白名单编辑落地。
- **风险与回滚**:纯工具改动,不发布任何包、不改运行时;最坏情况是门禁误红,回滚即还原这 7 个文件。
- **先看**:① `scripts/check-vouch-for-reference-callers.mjs` 的 `censusOf`
与 `ALLOWED_CALLERS`;② `.github/workflows/lint.yml` 的 Single authz
resolver guard 步骤;③ `scripts/cross-package-test-inputs.mjs` 的 core
条目注释(`packages/**` `.ts` 边界)。
- **两分钟验证**:`pnpm check:vouch-for-reference-callers`,预期两行 ✓:self-test 39
cases pass,以及 `file-attachment-service.ts (2)`。
- **需要你做的**:本 PR 触及 `.github/workflows/**`(Tier H),需要维护者合并或授权批准。
## What changes
The only production code that may set the vouched-reference mark
(`vouchForReference`, `@objectstack/core`) is
`packages/services/service-storage/src/file-attachment-service.ts`, at
exactly two call sites (`attachFileAs` and `attachUploadAs`). This PR
adds a call-site census gate that holds that rule.
- `scripts/check-vouch-for-reference-callers.mjs`. Outside the defining
module, every mention of `vouchForReference`, `VOUCHED_REFERENCES` or
the key's `Symbol.for` description, in code or in a string literal, is
exactly one of three things:
1. A direct call, which is counted.
2. An unrenamed `import`/`export … from` specifier, which sets nothing.
3. A finding, naming the file and line. This covers renames on import or
export, namespace or member access, bracket or string-keyed access,
value aliases, `.call`/`.apply`, `require` destructuring, the key as a
computed property or as an argument to
`Object.defineProperty`/`Reflect.set`, and the description in any
literal.
A `Symbol.for(…)` whose argument is not a plain literal, an
unsubstituted template, or a same-file `const` bound to a plain literal
is a finding too. Counted calls are held equal to `ALLOWED_CALLERS`. A
new caller, a count that moves either way, or a stale row is red. The
stale-row message names both remedies: remove the row, or restore the
call. Code is told from comments by `maskComments`
(`scripts/js-comment-mask.mjs`), and `Symbol.for` arguments are read off
`maskCommentsAndLiterals`. Test files are outside the census, and an
empty scan is refused. The `--self-test` carries a 39-battery roster
with a floor and the verdict handshake.
- **Surfaces.** The bare run reads `packages/`, `examples/` and `apps/`
over every source extension. It runs in the lint step on every PR,
uncached, and it is the authority. `--ts-only` reads `packages/**` `.ts`
alone. That is the radius of the `@objectstack/core` pin (its
declaration-table entry and `test:repo` turbo inputs, which also name
the script), so what the pin judges equals what re-runs it.
`ROOT_DIR_WATCH_HINTS` spells the three roots as subtrees for the
dispatch derivation, as `check-org-identifier.mjs` does over the same
roots. The self-test holds it equal to `SCAN_ROOTS`.
- Root alias `check:vouch-for-reference-callers` (self-test, then scan),
wired into the existing `Single authz resolver guard` step of
`lint.yml`. No new check context and no new required-status entry.
- `packages/core/src/security/vouched-reference-callers.pin.test.ts`,
listed in `vitest.repo-tests.json`, runs `--self-test` and `--ts-only`
where `Test Core` runs them.
The allowlist was re-read against `main` (`37371559b`): the file holds
exactly two `vouchForReference(` calls, and nothing else under the three
roots mentions the mark outside a comment. The tree has 57 `Symbol.for`
code sites, and all of them are readable.
## Tests
- Core `repo` project: 7 files / 96 tests pass on `ef6658f2d1`. The pin
is compiled by `tsconfig.test.json` with no new test-typecheck debt.
- Tree ablations, each through `scripts/ablation-replace.mjs`, with the
restore proven by blob equal to HEAD and an empty `git diff HEAD`. Each
injection reds the bare run, naming the file:
- a call in `packages/rest/src/query-allowlist.ts` (also red under
`--ts-only`, and the pin goes red);
- removing the `attachFileAs` call (row pins 2, file holds 1);
- `import { VOUCHED_REFERENCES as MARK }` (line 2);
- `Symbol.for(PREFIX + …)` with an imported constant (line 3);
- a value alias of `vouchForReference` (line 3);
- a call after `'https://…'` on the same line;
- a call in `examples/app-crm/src/actions/convert-lead.action.ts`, which
is green under `--ts-only` by design;
- a call in a `.mjs` file under `packages/`, which is green under
`--ts-only` by design.
- Rule ablations in the script itself. Each one turns its batteries red:
- rename finding off: 3 batteries;
- mention finding off: 13;
- `Symbol.for` argument rule off: 2;
- `maskComments` swapped for a `//`-to-end-of-line strip: 2;
- `examples`/`apps` dropped from `SCAN_ROOTS`: 1;
- stale-row remedy text cut: 1;
- a root dropped from, or added to, `ROOT_DIR_WATCH_HINTS`: 2 and 1.
- Removing the alias line from `lint.yml` reds `check-self-test-wired`
(`alias-self-test-not-run`).
## Acceptance notes
- Tier H: the diff touches `.github/workflows/lint.yml`.
`check-governed-merges --pr` names exactly that path, landing tier H,
588 changed lines, under the 3,000-line threshold.
- No published package moves. The only file under a package is a
`*.test.ts` in `@objectstack/core`, which ships `dist` only. Check
Changeset route 2 applies, through the `skip-changeset` label.
- The step runs its two commands under the default `bash -e`, so a red
`check:authz-resolver` stops the census from running in that same step.
The step is red either way.
## Verification
<details><summary>Gate run</summary>
```
✓ check-vouch-for-reference-callers self-test: 39 cases pass.
✓ check-vouch-for-reference-callers: every call site that sets the vouched-reference mark is allow-listed (packages/, examples/, apps/, every source extension) — packages/services/service-storage/src/file-attachment-service.ts (2).
✓ check-vouch-for-reference-callers: every call site that sets the vouched-reference mark is allow-listed (the .ts surface) — packages/services/service-storage/src/file-attachment-service.ts (2).
```
</details>
<details><summary>Derived gate families</summary>
`dispatch-gates --commands` derives 94 commands on the final head
`ef6658f2d1`; all 94 exit 0 and `--ran` reconciles 94 run, 0 unrun.
`dispatch-gates --self-test --fast` (1954 cases), `bare-root-worklist
--self-test`, `check-watch-hint-literal --self-test`,
`check-self-test-wired` and `check-comment-mask-adoption` are green, and
every check-run on `ef6658f2d1` concluded success or skipped.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L9qibvynRbCtMndW8EHNGc)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 7faa237 commit ad06144
7 files changed
Lines changed: 585 additions & 3 deletions
File tree
- .github/workflows
- packages/core
- src/security
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2550 | 2550 | | |
2551 | 2551 | | |
2552 | 2552 | | |
| 2553 | + | |
| 2554 | + | |
| 2555 | + | |
| 2556 | + | |
| 2557 | + | |
| 2558 | + | |
| 2559 | + | |
| 2560 | + | |
2553 | 2561 | | |
2554 | 2562 | | |
2555 | 2563 | | |
2556 | | - | |
| 2564 | + | |
| 2565 | + | |
| 2566 | + | |
2557 | 2567 | | |
2558 | 2568 | | |
2559 | 2569 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
| 209 | + | |
209 | 210 | | |
210 | 211 | | |
211 | 212 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
0 commit comments