Row 286 C2-03b: fold dewey-0860 (Q1 sh fd/inode check, Q2 chief by roles definition, N1-N3)

This commit is contained in:
jason.woltje committed 2026-10-24 04:55:04 -05:00
1 parent 6ce15eddd5
commit c2c4ac6793
1 file changed
+44
+44
View File
@@ -113,3 +113,47 @@ argv, the mirror config, the run log and the test output. Mutant: a `+` added to
Dewey approves the manifest. The library and bus suites, plus every `scripts/test-*.sh`, pass on Sage's
gate. The mutant dies. A token search of the run's output finds nothing.
## Early look (dewey-0860), folded
Q1, askpass: sh, with no gap between the check and the read. The helper keeps `test -f` and then:
- opens the slot with `exec 3<"$slot"`;
- stats the open file with `stat -L -c '%d:%i %u %a %s %F' /dev/fd/3`, and the path itself (an lstat)
with `stat -c '%d:%i' -- "$slot"`;
- refuses unless the two dev:inode values match, the type is regular, the uid is `id -u`, the mode is
600 and the size is at most 16384;
- reads the token from fd 3.
A symlink or a swap at either moment changes the inode, and the token comes from the file that was
checked. This matches `readSecretFile` (`gitea-grant.mjs:167-181`).
Residual, the same on both paths: a FIFO swapped in after `test -f` blocks the open. Neither side uses
O_NONBLOCK.
Swap test T5b: the direct helper test puts a `stat` shim on its own PATH. On its first call the shim
renames another file over the slot, then runs the real stat. The helper must exit 1 and print nothing.
Mutant M2 drops the inode compare and must fail T5b.
Q2, the chief: found through `roles` by definition, not through `launch.instances`. A fire only delists
the name (`packages/business/src/instance-settings.mjs:355`), and `roles[name]` stays. Only a delete
removes it (`deletedDocument`, :70).
- Gitea grant evidence for any `roles` entry whose definition is `chief-of-staff` ends the fallback.
That includes a fired chief beside a new listed one.
- A live credential comes only from the listed chief's live, unheld `gitea_grants` row.
- With no `roles` entry of that definition (deleted, or never a chief), any gitea grant event in the
business refuses `library-fetch-no-grant`.
- Cost, for Sage: row 236 lets seat gitea grants exist before C2-21. So a business with no chief
entry and one seat grant loses the slot fallback. That fails safe, but it narrows "an install that
runs before C2-21 still syncs".
- T7's fired case also asserts that `roles[chief]` still exists after `instance.fire`.
N1: the `credential` key is optional in `mirror.mjs`'s exact `keys(...)` check (:221), so a pre-286
state file still reads. The old fixtures have no `credential`: `library-sync.test.mjs:18`,
`library.test.mjs:106` and `mirror.test.mjs:13`. New test T12 reads a pre-286 state file. Row 224
(Della, 23816cf28) also changes `packages/bus/src/runtime.mjs`. Whichever lands second rebases and reruns
bus whole.
N2: `[remote rejected]`, a hook refusal, is `library-push-failed`, not a race. Only `[rejected]` with
`(fetch first)` or `(non-fast-forward)` counts as a race. The evidence query depends on
`body.method` and `body.agent`. gitea `grant.applied` carries both at `broker.mjs:2479` and
`grant.revoked` at :1862 and :2797. The spend event (`operation: 'grant.gitea'`, :1093) carries
neither, so it doesn't match.
N3: `fetchCredential` reads the store, so it is the bus's choice function, not a pure one.