Repository navigation
Commit 6b83ec2
ci(lint): run check:liveness in the required source-gates lane on every change (#31559)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbGJxVR6gZPrpPRHctVZA2h9)_
Part of #31518
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:在必跑的 `Type Check · source gates` 检查里加了一步 `pnpm --filter
@objectstack/spec check:liveness`,每个 PR 和每个合并队列条目都会跑,不再按路径过滤。
- **为什么改**:spec 的属性台账会引用全仓库的源码文件。只改了被引用文件(比如 objectql 的 engine.ts)的
PR,原来的检查要么没被触发,要么从 turbo 缓存直接回放成绿色;上周 #30341 带着红色的台账检查合进了 main,#30716
在队列里红了两次。
- **风险与回滚**:风险低。这一步只读源码,不需要 build,约 4 秒;判定逻辑一行没改。回滚就是删掉这一个 step。
- **先看**:`.github/workflows/lint.yml` 里新增的 step 和它上面的注释。
- **两分钟验证**:在当前 main 上跑 `pnpm --filter @objectstack/spec
check:liveness`,应该退出 0;再看下面"Verification"里 #30341 和 #30716 的树上它退出 1 的记录。
- **需要你做的**:这是 Tier H 的 workflow 改动,请你手动合并;`spec-liveness-check.yml`
的去留留给 seat 决定(见下方 Follow-ups)。
## What changes
One step is added to the `typecheck-source-gates` job (`Type Check ·
source gates`) in `.github/workflows/lint.yml`:
```yaml
- name: Check every spec liveness citation still names its property
id: check-spec-liveness-citations
continue-on-error: true
run: pnpm --filter @objectstack/spec check:liveness
```
It follows the lane's existing shape. The step carries
`continue-on-error: true` and an `id:`, and the job's `Lane verdict`
step reads its outcome from `toJSON(steps)`, so a red here reds the
lane. The lane has no `paths:` filter. Its only `if:` skips a scheduled
run that a green push run already covers, so the step runs on every
`pull_request` and every `merge_group`. The required `TypeScript Type
Check` aggregate already depends on this job, so no required context is
added or dropped.
The command and its logic are unchanged. `spec-liveness-check.yml` is
untouched.
## Why
Step 1 on #31518 classed 68 red merge-queue roots from 2026-11-01..07.
Class (b), "not selected on the PR", had 6 roots and 23 cascades. Four
of those roots are this one shape: the spec property-liveness ledger
(`packages/spec/liveness/`) cites evidence files across the whole tree,
and a PR that only moves code in a cited file makes a citation stale
without either existing runner catching it.
- `Spec property liveness` (`spec-liveness-check.yml`) is scoped by
`paths:` to the spec side on `pull_request` and is not a required
context. Its red `merge_group` run does not stop the entry from landing.
In the window, #30341, #30353, #30351 and #30298 landed with that run
red, and #30341 left main failing the command until #30368.
- `check-liveness.test.ts` runs inside `@objectstack/spec:test`, whose
turbo hash covers spec inputs only. #30716's PR run replayed `spec:test`
from the cache (hash `09ab3604`) and went green; its queue entry missed
the cache (`86ebed7f`) and went red, twice.
The command reads source through tsx and needs no build. At the current
head it exits 0 in about 4 s with `dist/` absent.
## Verification
Proof method: **reproduction on scratch detached worktrees**. For each
tree, a detached worktree was checked out, `pnpm install
--frozen-lockfile` was run, and the lane's exact command was run. Each
red tree is paired with its parent as a CONTROL.
| Tree | What it is | Exit | Stale citation |
|---|---|---|---|
| `f672e0dc5` | #30341's landed tree | 1 | `query/searchFields` →
`packages/objectql/src/engine.ts` |
| `8589756a` | its parent (CONTROL) | 0 | none |
| `198d1125` | #30716's queue entry | 1 | `manifest/contributes.kinds` →
`packages/objectql/src/engine.ts` |
| `dc5217d8` | that entry's queue parent (CONTROL) | 0 | none |
| `3e387e33` | #30716's PR head | 1 | `manifest/contributes.kinds` |
The last row is the card's CONTROL shape. #30716's PR head fails the
command, while its PR run was green because `spec:test` was a cache hit
and `Spec property liveness` was not scheduled. With this step, that PR
run would have gone red on the PR instead of in the queue.
<details><summary>Failing output (all three red trees print the same
shape)</summary>
```
✗ 1 'live' / 'planned' / 'experimental' / 'live-elsewhere' citation(s) name a file that never names the property:
manifest/contributes.kinds → packages/objectql/src/engine.ts
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL @objectstack/spec@18.3.0 check:liveness: `tsx scripts/liveness/check-liveness.mts`
Exit status 1
```
</details>
<details><summary>Current head: green with no build</summary>
```
✓ every governed-type property, at every depth the ledger drills, is classified, …
✓ packages/spec/liveness/state-counts/ is current — one shard per governed type, the same 44 row(s) as the README, no count column left in the README.
```
</details>
**Derived gates.** `node scripts/pm/dispatch-gates.mjs --commands`
derives 42 families for this diff. All 42 were run and exited 0, and
`--ran` reconciles them: 42 derived, 42 run, 0 NOT-MEASURED. `node
scripts/ci/lane-verdict.mjs --self-test` (31 cases) and the lane command
itself were also run green. After main was merged, the derivation is
unchanged; the merge brought in no workflow file.
**Family row.** None is added to `dispatch-gates.data.mjs`.
`check:liveness` is already a discovered family (a change to
`packages/spec/scripts/liveness/check-liveness.mts` derives `pnpm
--filter @objectstack/spec run check:liveness`), and the derivation's
own roster gates (`check:pm-dispatch-gates`, `check-step-collectors`,
`check:aggregator-roster`, `check:required-contexts`) are green with the
new step in place.
## Other classes from step 1
- **(a) stale base**: 21 roots and 122 cascades, the largest class. It
is not a CI-side fix. It is filed as #31548 (domain:skills), an
enqueue-time refresh.
- **(b) dogfood**: the 2 remaining (b) roots are the ruled two-speed
design, so there is no change there.
- **(c) flake**: 36 roots and 5 cascades. These are covered by #30785,
#30555, #31284, #31312, #22034/#31429, #31213 and #31195.
- **(d) genuine**: 0 roots.
## Follow-ups
- **For the seat: retire or keep `spec-liveness-check.yml`.** Its
`check:liveness` step is now a duplicate of this one. The workflow also
runs `check:empty-state`, `check:variant-docs` and
`check:strictness-ledger`, which this PR does not move. This diff leaves
it as it is.
- A local derivation gap remains. `dispatch-gates` derives
`check:liveness` for a change under `packages/spec/` but not for a
change that touches only a cited file, such as
`packages/objectql/src/engine.ts`. CI now catches that case on the PR,
so a dev who skips it locally gets a red on the PR rather than in the
queue.
## Re-reading (7 days after this lands)
Repeat step 1's method over the 7 days after this merges. Expect class
(b) liveness roots to drop to 0.
When classing, count a red as a **cascade, not a root, if its nearest
red ancestor failed the same test**. A `merge_group` entry selects Test
Core and Test UI by `git diff base_sha HEAD`, and `base_sha` is the
entry directly ahead, so an entry behind a red one does not re-run the
red one's test. A one-hop rule therefore labels some transitive cascades
as roots (5 roots and 7 cascades in step 1).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(No schema is touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran. (Only a workflow file changes, so there is no
source for `pnpm lint` to judge.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset. (Nothing
publishes: `skip-changeset`.)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Not touched.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jVWeBc5ThsX5K8ymDr)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 02996c1 commit 6b83ec2
1 file changed
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5210 | 5210 | | |
5211 | 5211 | | |
5212 | 5212 | | |
| 5213 | + | |
| 5214 | + | |
| 5215 | + | |
| 5216 | + | |
| 5217 | + | |
| 5218 | + | |
| 5219 | + | |
| 5220 | + | |
| 5221 | + | |
| 5222 | + | |
| 5223 | + | |
| 5224 | + | |
| 5225 | + | |
| 5226 | + | |
| 5227 | + | |
| 5228 | + | |
| 5229 | + | |
| 5230 | + | |
| 5231 | + | |
| 5232 | + | |
| 5233 | + | |
| 5234 | + | |
5213 | 5235 | | |
5214 | 5236 | | |
5215 | 5237 | | |
| |||
0 commit comments