test: skip the mode-bit arms when the runner is root #228

Merged
john merged 1 commit from fix/ci-root-mode-bits into main 2026-08-22 14:49:03 +00:00
Owner

node-test (routing, 22) and (routing, 24) have been red on main since the
runner started executing as root. Three tests in
cadence-core/bin/phase-plans.test.mjs chmod a fixture to 0o000 and assert
that the unreadable plan or archive directory is skipped:

  • an unreadable plan does the same: no path, one warning, clean below found
  • the by-path reader carries the out-of-grammar and unreadable arms too
  • an unreadable archive directory is skipped, never a throw

Root ignores mode bits, so on the runner the fixtures read back fine, the
"unreadable" plan parses, and all three assertions fail. Every local non-root
run is green, which is the whole local/CI gap - the production code is not
involved.

Guarded with the idiom planning.test.mjs:4187 already uses for its own
mode-bit arm:

skip: typeof process.getuid === 'function' && process.getuid() === 0 ? 'root bypasses mode bits' : false,

Verified by reproduction rather than by assumption, using a user namespace to
get a real uid 0:

  • unshare -r node --test cadence-core/bin/phase-plans.test.mjs before the
    change: 27 tests, 3 fail - the same three, by name, that CI reports.
  • After the change: 27 tests, 0 fail, 3 skipped with # SKIP root bypasses mode bits.
  • node cadence-core/bin/test.mjs routing exits 0 both as the ordinary user and
    under unshare -r; tsc -p tsconfig.ci.json exits 0.
  • risk-check run on the range: no category matched, not inconclusive.

The arms still run for every non-root developer and in any non-root runner.

`node-test (routing, 22)` and `(routing, 24)` have been red on `main` since the runner started executing as root. Three tests in `cadence-core/bin/phase-plans.test.mjs` `chmod` a fixture to `0o000` and assert that the unreadable plan or archive directory is skipped: - `an unreadable plan does the same: no path, one warning, clean below found` - `the by-path reader carries the out-of-grammar and unreadable arms too` - `an unreadable archive directory is skipped, never a throw` Root ignores mode bits, so on the runner the fixtures read back fine, the "unreadable" plan parses, and all three assertions fail. Every local non-root run is green, which is the whole local/CI gap - the production code is not involved. Guarded with the idiom `planning.test.mjs:4187` already uses for its own mode-bit arm: ```js skip: typeof process.getuid === 'function' && process.getuid() === 0 ? 'root bypasses mode bits' : false, ``` Verified by reproduction rather than by assumption, using a user namespace to get a real uid 0: - `unshare -r node --test cadence-core/bin/phase-plans.test.mjs` before the change: 27 tests, 3 fail - the same three, by name, that CI reports. - After the change: 27 tests, 0 fail, 3 skipped with `# SKIP root bypasses mode bits`. - `node cadence-core/bin/test.mjs routing` exits 0 both as the ordinary user and under `unshare -r`; `tsc -p tsconfig.ci.json` exits 0. - `risk-check run` on the range: no category matched, not inconclusive. The arms still run for every non-root developer and in any non-root runner.
test: skip the mode-bit arms when the runner is root
All checks were successful
test / node-test (git, 22) (pull_request) Successful in 30s
test / node-test (git, 24) (pull_request) Successful in 27s
test / node-test (other, 22) (pull_request) Successful in 1m8s
test / node-test (other, 24) (pull_request) Successful in 1m4s
test / node-test (planning, 22) (pull_request) Successful in 1m27s
test / node-test (planning, 24) (pull_request) Successful in 1m27s
test / node-test (prose, 22) (pull_request) Successful in 31s
test / node-test (prose, 24) (pull_request) Successful in 29s
test / node-test (review, 22) (pull_request) Successful in 16s
test / node-test (review, 24) (pull_request) Successful in 16s
test / node-test (routing, 22) (pull_request) Successful in 33s
test / node-test (routing, 24) (pull_request) Successful in 32s
test / self-verify (pull_request) Successful in 11s
test / typecheck (pull_request) Successful in 16s
8fdfb6d4a8
The three chmod-0o000 tests in phase-plans.test.mjs assert that an
unreadable plan or archive directory is skipped. Root ignores mode bits, so
on a CI runner executing as root the fixtures read back fine and all three
assertions fail - node-test (routing, 22) and (routing, 24) have been red
since the runner moved to root, while every local non-root run is green.

Guard them with the idiom planning.test.mjs already uses for its own
mode-bit arm: skip when getuid() is 0, with the reason said out loud.
john merged commit 1497b9c6bf into main 2026-08-22 14:49:03 +00:00
Sign in to join this conversation.
No description provided.