morgana: row 257 r2 (filbert r1 N1, N2): Object.hasOwn unknown-key refusal with inherited-name cases; critical memory edge on a 20 GiB limit (M8)
This commit is contained in:
1 parent
9ffa507302
commit
1261fa2d87
3 files changed
+24
-2
No files matched your search
@@ -81,6 +81,20 @@ Other readings of the D4 table, made in the build:
|
||||
- **Large byte values.** Parsed with `Number`. A memory.max above 2^53 loses precision, but it only
|
||||
takes part in a min against MemTotal.
|
||||
|
||||
## Round 2 (Filbert r1 APPROVE c30188 notes, sage-2212)
|
||||
|
||||
- N1: `merge` checked unknown keys with `key in base`, so inherited names (`toString`, `constructor`,
|
||||
`__proto__`) passed the check and were dropped instead of refused. It now uses
|
||||
`Object.hasOwn(base, key)`, and the refusal test has those three cases.
|
||||
- N2: the critical-memory edge was tested only on a 32 GiB limit, where 5% is not an integer, so a
|
||||
`<` to `<=` mutant survived. The test adds a 20 GiB limit, where 5% is exactly 1 GiB, and M8 is that
|
||||
mutant. I checked the other memory edges for the same gap:
|
||||
- The hold floor is non-integer on 32 GiB but is tested at exactly 1 GiB on a 4 GiB limit.
|
||||
- The release floors are 8 GiB on 32 GiB and 2 GiB on 4 GiB, both integers.
|
||||
- The disk edge is 1 GiB.
|
||||
|
||||
None has the gap.
|
||||
|
||||
## Files
|
||||
|
||||
- `packages/supervisor/package.json`, `README.md`
|
||||
@@ -117,12 +131,13 @@ dependency.
|
||||
| M5 stale | the `now - signal.at > rules.staleMs` check is removed | a signal is stale at more than 6 s old and fresh at exactly 6 s |
|
||||
| M6 effective CPU | the quota `Math.min` becomes `Math.max` | effective CPUs take the smallest of host, cpuset and every quota level |
|
||||
| M7 critical latch | the `!reconciled` critical branch is removed | critical stays until reconciliation, then still waits the 30 s release |
|
||||
| M8 critical memory edge (r2) | `available < rules.critical.memoryFraction * limit` becomes `<=` | memory under 5% and disk under 1 GiB are critical, at their edges |
|
||||
|
||||
## Gate (Sage's slot, on CLEAR only)
|
||||
|
||||
- The three test files, each whole, then `node --test tests/` in packages/supervisor as the package
|
||||
suite.
|
||||
- Then M1 to M7, each on its named test, restored after each.
|
||||
- Then M1 to M8, each on its named test, restored after each.
|
||||
- umask 022, TMPDIR from `mktemp -d /mnt/storage/scratch/tmp/gXXXXXX`.
|
||||
- The kit is /mnt/storage/scratch/morgana-r257 (slot257.sh, mutate.py). It refuses unless HEAD is the
|
||||
candidate and the tree is clean, and stops after two unexpected failures (mos-0823).
|
||||
|
||||
@@ -36,7 +36,7 @@ function merge(base, over, at) {
|
||||
if (over === undefined) return structuredClone(base);
|
||||
if (!over || typeof over !== "object" || Array.isArray(over)) refuse(`${at || "rules"} must be an object`);
|
||||
const out = {};
|
||||
for (const key of Object.keys(over)) if (!(key in base)) refuse(`unknown key ${at ? `${at}.` : ""}${key}`);
|
||||
for (const key of Object.keys(over)) if (!Object.hasOwn(base, key)) refuse(`unknown key ${at ? `${at}.` : ""}${key}`);
|
||||
for (const [key, value] of Object.entries(base)) {
|
||||
const name = at ? `${at}.${key}` : key;
|
||||
if (typeof value === "object") out[key] = merge(value, over[key], name);
|
||||
|
||||
@@ -248,6 +248,10 @@ test("memory under 5% and disk under 1 GiB are critical, at their edges", () =>
|
||||
const mem = evaluate(opened(), sample(32000, { memory: { available: Math.ceil(five) - 1 } })).decision;
|
||||
assert.equal(mem.mode, "critical");
|
||||
assert.deepEqual(mem.reasons, ["critical-memory"]);
|
||||
// On 20 GiB the 5% line is exactly 1 GiB, so the edge itself is tested.
|
||||
const s20 = (available) => sample(32000, { memory: { available, limit: 20 * GiB } });
|
||||
assert.equal(evaluate(opened(), s20(1 * GiB)).decision.mode, "held");
|
||||
assert.deepEqual(evaluate(opened(), s20(1 * GiB - 1)).decision.reasons, ["critical-memory"]);
|
||||
assert.equal(evaluate(opened(), sample(32000, { disk: { free: 1 * GiB } })).decision.mode, "open");
|
||||
assert.deepEqual(evaluate(opened(), sample(32000, { disk: { free: 1 * GiB - 1 } })).decision.reasons, ["critical-disk"]);
|
||||
});
|
||||
@@ -322,6 +326,9 @@ test("contradictory or unknown settings refuse", () => {
|
||||
[{ critical: { diskBytes: 0 } }, /critical.diskBytes/],
|
||||
[{ loadd: {} }, /unknown key loadd/],
|
||||
[{ psi: { hold: { gpu: 1 } } }, /unknown key psi.hold.gpu/],
|
||||
[{ load: { toString: 1 } }, /unknown key load.toString/],
|
||||
[{ constructor: {} }, /unknown key constructor/],
|
||||
[JSON.parse('{"memory":{"__proto__":{}}}'), /unknown key memory.__proto__/],
|
||||
[{ load: { hold: "0.8" } }, /load.hold must be a finite number/],
|
||||
[{ load: 1 }, /load must be an object/],
|
||||
[[], /rules must be an object/],
|
||||
|
||||
Reference in new issue
Block a user