Repository navigation
Commit fc5e70e
test(runtime): the action-owner-key tree pin walks packages/ once, reading only the .ts files it judges, so a loaded Test Core shard stops timing it out (#25319)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DD9wftyCasRGvePSJjV8owb)_
Fixes #25298
Clause-②: no
Metadata-protocol: none
The hourly full run `39853791549` (`main` `49185cdb8a`) went red in
`Test Core (6/6)` on two packages. This PR makes the first one robust
and records why the second cannot be named from this session.
1. **`@objectstack/runtime#test:repo`.**
`src/action-owner-key-single-source.test.ts` took 86.24 s on the loaded
shard against its 60 s scan budget (0.3 s locally). Half D now walks
`packages/` once, reading only the `.ts` files it judges, instead of
three full walks. `SCAN_TIMEOUT_MS` stays `60_000`, and what the scan
proves does not narrow.
2. **`@objectstack/driver-sqlite-wasm#test`.** The failing test sits in
the part of job `120086810803`'s log this session cannot read. What was
tried is listed below. The red did not repeat: the next three scheduled
full runs are green.
Test-only; `skip-changeset` (the file is under `src/` and is not in
`@objectstack/runtime`'s `files[]`, which ships `dist`).
## Item 1: what the scan cost, and what changed
Half D asks three questions of the tree: which files name the dead
member (test 1), whether the scan sees this pin (test 2) and whether it
reaches the live helper outside this package (test 2). Each question was
its own `git grep --untracked` over **every file** under `packages/`,
filtered to `.ts` afterwards. So one run read the whole root three
times.
Now:
- **One `git grep`** carries both hunted symbols (`-e actionObjectKey -e
standaloneActionOwnerKey`). It runs once in the describe's `beforeAll`,
which carries the unchanged `SCAN_TIMEOUT_MS`, and both tests read its
answer. The candidate files (11 today) are read to attribute each symbol
and line. If git lists a file and the read finds neither needle, the
scan throws: a broken scan, never a clean file.
- **The pathspec is the declared glob.** `SCANNED_PATHSPECS` derives
`:(glob)packages/**/*.ts` from `SCANNED_ROOTS` and `SCANNED_EXTENSION`.
That is the same glob the package declares in
`scripts/cross-package-test-inputs.mjs`, so git reads only the files the
scan judges. It no longer reads the other quarter of the bytes (the
`CHANGELOG.md`s alone are 55 MB) just to throw them away.
- **The reach control gets tighter.** Test 2 now checks the very scan
whose emptiness test 1 reads, not a separate run of it. If pathspec
magic were ever turned off (`GIT_LITERAL_PATHSPECS`), the scan would
match nothing and test 2 would go red.
### Readings (local container, under `scripts/pm/os-verify-lock.sh`;
base `21a25dd9`, head `0a77f624`)
| reading | before | after |
| :-- | --: | --: |
| `git grep` invocations per file run | 3 | 1 |
| bytes git reads per file run (`rchar` from `/proc/PID/io`, the test's
own arguments) | 3 × 212.6 MB = 637.8 MB | 151.2 MB |
| read syscalls per file run | 3 × 10,061 | 9,345 |
| file wall, vitest JSON reporter, 3 runs each | 311 / 332 / 327 ms |
122 / 123 / 114 ms |
| half D tests | 101–107 ms and 197–219 ms | 1 ms and 1 ms (the scan
runs in `beforeAll`) |
| `vitest run --project repo` (3 files) | 808 passed, 15.47 s | 808
passed, 17.07 s |
The bytes read drop to a quarter (−76%). The local wall clock can't
reproduce the shard's slowdown: the same scan takes 0.1 s here and about
29 s per full walk there (86.24 s across three walks). **Estimate, not
measured on a shard:** if the shard's cost scales with bytes read, one
`.ts` walk there is about 20 s, a third of the unchanged 60 s budget.
### The scanned set did not narrow: measured
The old judged set was an unscoped `git grep` plus `.endsWith('.ts')`.
The new one is the `:(glob)packages/**/*.ts` grep. The two were compared
per symbol on this tree, with untracked plants added at
`packages/zz-eq-25298/top.ts` (depth 1), `…/a/b/deep.d.ts` (depth 3),
`…/a/b/note.md`, `…/a/b/x.tsx` and `…/a/b/y.mts`:
| symbol | old set | new set | identical |
| :-- | --: | --: | :-- |
| `actionObjectKey` | 4 | 4 | yes |
| `standaloneActionOwnerKey` | 11 | 11 | yes |
Both sets keep the two `.ts` plants (`.d.ts` included) and both leave
out the `.md`, `.tsx` and `.mts` plants. All plants were removed
afterwards, and `git status` was clean.
### A planted occurrence in a still-scanned path goes red
Predicted direction: red, naming the site. Each run was the pin file
alone under the verify lock, after the fix was committed.
| leg | mutation | result |
| :-- | :-- | :-- |
| tracked file | `scripts/ablation-replace.mjs` plants the dead name in
a comment of `packages/objectql/src/action-governance.ts` (anchor 1 → 0,
blob `1d91722f355a` → `d7eb77aaf2ee`) | 1 failed, 15 passed; the failure
lists `packages/objectql/src/action-governance.ts:41`. Restored: blob
equals HEAD (`1d91722f355a`), `git diff HEAD` empty |
| untracked, three levels deep |
`packages/plugins/plugin-auth/src/zz-ablation-25298/deep/planted.ts`
naming the dead member | 1 failed, 15 passed; the failure lists
`…/deep/planted.ts:1` |
| control: same text, `.md` | the same directory, `planted.md` only | 16
passed, as on base (the base filtered to `.ts` too) |
The plant directory was removed by a trap, and `git status` was clean
afterwards.
## Item 2: `driver-sqlite-wasm`, the failing test not named
**Not identified.** The turbo summary and the annotations name the task,
not the test. What was tried:
- **MCP `get_job_logs`** returns the last 4,999 of the log's 43,666
lines, from 21:20:45Z onward. That part is `@objectstack/runtime:test`'s
output, then turbo's summary. `driver-sqlite-wasm`'s own output comes
earlier.
- **The job log's signed URL**
(`productionresultssa2.blob.core.windows.net`, by the API's 302 or the
MCP URL) is refused by this session's egress proxy: `CONNECT tunnel
failed, response 403`.
- **The run's log archive** (302 to
`results-receiver.actions.githubusercontent.com`) is refused the same
way. A WebFetch of the signed URL is refused as too long.
- **The check-run annotations** (`GET
/check-runs/120086810803/annotations`, answered 200) carry only turbo's
two `exited (1)` lines and the exit-code line. No vitest annotation is
there.
- **The summary job's timing table** (job `120098319014`) lists only the
slowest 20 files, and no `driver-sqlite-wasm` file is among them. The
full merged table (artifact `test-core-timing-table`, ID `12460740336`,
kept 14 days) and shard 6's capture (`test-core-timings-6-of-6`, kept 1
day) download from the same blocked blob host.
**What the reachable part does say:** `check-test-completeness: OK (14
of 14 scheduled package(s) reported, 0 had nothing to run, 0 never
reached; 33419 test(s) declared and all accounted for)`. So
`driver-sqlite-wasm`'s vitest run reached its own summary: it was not a
worker crash before the summary. Whether it was a failed assertion, a
timeout or an unhandled error is in the unread part.
**Still recoverable:** from a session whose egress allows
`productionresultssa2.blob.core.windows.net`, or from the Actions web UI
while signed in. The job log is kept about 90 days, and the merged
timing artifact until about 2026-11-05.
**Recurrence:** scheduled `CI` runs `39861781058` (22:01Z,
`5801a4f2c9`), `39868952638` (23:00Z, `09e07c259a`) and `39875645832`
(00:02Z, `258f4e6aaa`) all concluded `success`.
## Local verification (head `0a77f624`)
- The dependency closure was built first, `pnpm
--workspace-concurrency=2 --filter '@objectstack/runtime^...' build`:
`VERDICT command-exit 0`.
- `pnpm --filter @objectstack/runtime exec vitest run --project repo`:
`VERDICT command-exit 0`, 3 files, 808 passed.
- `pnpm --filter @objectstack/runtime typecheck`: `VERDICT command-exit
0` (`tsc --noEmit`; `check:test-typecheck` OK, 27 files / 190 errors /
68 pinned signatures held).
- `eslint --no-inline-config` on the changed file: exit 0. No control
bytes.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 53 families; 52 exit 0.
`check-plugin-teardown-shape --self-test` first exited 3 (its pinned
fixture commit was outside the shallow clone) and exited 0 once that
commit was fetched. `check:dual-build-cjs-loads` exits 3, PREREQUISITE
NOT MET: it needs every package's `dist`, and this container built only
runtime's closure. **NOT MEASURED locally**; its verdict is this PR's
`Lint & Repo Gates` check.
- `--ran` reconciliation: `53 derived famil(ies) accounted for — 52 run,
1 NOT-MEASURED (1 DERIVED from a recorded exit 3)`.
- `origin/main` has moved to `9dc1f42d` since the base. The only change
it brought under `packages/runtime` or `packages/objectql` is a 13-line
change to `src/security/resolve-execution-context.test.ts`, and on that
tree the scan's sets read the same (the two pins; `lint.ts` and
`action-governance.ts` reached), so no merge was made.
## Acceptance notes
- **The `@objectstack/objectql` twin has the same three-walk shape.**
`packages/objectql/src/action-owner-key-single-source.test.ts` (half D
at about `:261` to `:383`) runs the same three unscoped walks under the
same 60 s budget. It did not time out in this run, but it carries the
same exposure. It is outside this card's file surface and is left
untouched. The pins are kept as two copies on purpose, so the same edit
there keeps them parallel.
- **Base readings for the card:** no open PR touches the pin file. Of
the 16 open PRs, read by title, only `#25318` changes
`packages/runtime/src`; its file list (read) is `action-execution.ts`
(which halves B and C read), a test and a changeset, and its added lines
carry no bare object-less literal. The file's last change on `main` is
`a186aea996` (2026-09-29), per GitHub's path history; `2354058` does not
touch it.
- **Branch name.** This PR's branch is `claude/project-thread-m55hn0`,
the name the session was given, not `claude/issue-25298-…`. The
Duplicate Fix Guard may say so. The claim (comment 6354110086) names it.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01AQLt9RhDuqVWK3Zt4aAwsE)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01AQLt9RhDuqVWK3Zt4aAwsE
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9a48ae8 commit fc5e70e
1 file changed
Lines changed: 104 additions & 22 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | | - | |
| 48 | + | |
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
| |||
325 | 325 | | |
326 | 326 | | |
327 | 327 | | |
328 | | - | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
329 | 349 | | |
330 | | - | |
331 | | - | |
332 | | - | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
333 | 356 | | |
334 | 357 | | |
335 | 358 | | |
| |||
349 | 372 | | |
350 | 373 | | |
351 | 374 | | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
352 | 381 | | |
353 | | - | |
354 | | - | |
355 | | - | |
356 | | - | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
357 | 399 | | |
358 | | - | |
359 | | - | |
| 400 | + | |
| 401 | + | |
360 | 402 | | |
361 | 403 | | |
362 | 404 | | |
363 | 405 | | |
364 | 406 | | |
365 | 407 | | |
366 | | - | |
367 | | - | |
| 408 | + | |
368 | 409 | | |
369 | | - | |
370 | | - | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
371 | 454 | | |
372 | 455 | | |
373 | 456 | | |
374 | 457 | | |
375 | 458 | | |
376 | | - | |
| 459 | + | |
377 | 460 | | |
378 | | - | |
379 | | - | |
380 | | - | |
381 | | - | |
| 461 | + | |
382 | 462 | | |
383 | 463 | | |
384 | 464 | | |
385 | 465 | | |
386 | 466 | | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
387 | 471 | | |
388 | 472 | | |
389 | 473 | | |
| |||
413 | 497 | | |
414 | 498 | | |
415 | 499 | | |
416 | | - | |
417 | 500 | | |
418 | 501 | | |
419 | 502 | | |
| |||
434 | 517 | | |
435 | 518 | | |
436 | 519 | | |
437 | | - | |
438 | 520 | | |
439 | 521 | | |
0 commit comments