Files
stack/agents/darkwing/work/queue-62/out/mutants-round3.sh
T
jason.woltjeandClaude Opus 5.5 90e568624f row 62 (#1555) round 3 packet: confirm read before a child drops, candidate 8b81e836
R2/B1: after a forbidden or not-found refusal on a child, the tick reads
GET /projects/<id> and drops the child only on 403 or 404; a deleted
kanban view (project read 200) fails the tick as in round 1. Tests 18
and 19, 23/23 mutants killed, gate on ae428a54 green (14 suites).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 15:54:19 -05:00

49 lines
4.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Round 3. Same method as mutants-round2.sh: each mutant edits one source file in the build worktree,
# runs the tests, then restores the file from the worktree index (the round 3 candidate). Rounds 1
# and 2 run again first, with the round 2 lines retargeted at the new leftTree(). Each runs only the
# test file that should fail it, since another seat's suite shared the machine; the gate runs every
# suite on the candidate.
export TMPDIR=~/darkwing-scratch/r62/tmp
cd ~/darkwing-scratch/r62/build
S=packages/tasks/src/sync.mjs; U=packages/tasks/src/startup.mjs; T=packages/tasks/tests/tree.test.mjs
run() { # name file sed-expr test-file
sed -i "$3" "$2"
if git diff --quiet -- "$2"; then echo "$1: MUTATION DID NOT APPLY"; return; fi
env -u NODE_TEST_CONTEXT node --test --test-timeout=30000 "$4" > ~/darkwing-scratch/r62/tmp/mut3-$1.log 2>&1
echo "$1: rc=$? $(grep -E '^ℹ (pass|fail) ' ~/darkwing-scratch/r62/tmp/mut3-$1.log | tr '\n' ' ')"
grep -E '^✖ ' ~/darkwing-scratch/r62/tmp/mut3-$1.log | sed 's/ ([0-9.]*ms)$//; s/^/ /' | sort -u | head -6
git checkout -q -- "$2"
}
# Round 1.
run no-leave-tree-check $S 's/} else if (!ctx.tree.has(project)) {/} else if (false) {/' $T
run no-watch-only-bucket $S 's/^const fieldsFor = .*/const fieldsFor = (task, bucket) => taskFields(task, bucket);/' $T
run placed-by-id $S 's/placed.add(ref(project, id));/placed.add(id);/; s/.filter((r) => !placed.has(r));/.filter((r) => !placed.has(parseRef(r).task));/' $T
run keep-archived $U 's/if (p.is_archived || p.id === ctx.project) continue;/if (p.id === ctx.project) continue;/' $T
run config-drops-descendants packages/cli/src/config.mjs 's/ descendants: v\["tracker.descendants"\],/ descendants: false,/' packages/cli/tests/config.test.mjs
# Round 2: R1, retargeted at the async leftTree().
run r2-child-refuses $S 's/ if (!(await leftTree(ctx, project, e))) throw e;/ throw e;/' $T
run r2-skip-keeps-child $S 's/ ctx.tree.delete(project);//' $T
run r2-root-drops $S 's/ if (project === ctx.project || !(e instanceof BusError)/ if (!(e instanceof BusError)/' $T
run r2-any-error-drops $S "s/ || (e.code !== 'tracker-forbidden' \&\& e.code !== 'tracker-not-found')) return false;/) return false;/" $T
run r2-403-only $S "s/(e.code !== 'tracker-forbidden' \&\& e.code !== 'tracker-not-found')/e.code !== 'tracker-forbidden'/" $T
run r2-404-only $S "s/(e.code !== 'tracker-forbidden' \&\& e.code !== 'tracker-not-found')/e.code !== 'tracker-not-found'/" $T
# Round 2: Filbert's N1 to N3, under the names Filbert used. Filbert's edits may differ from these.
run tree-early $U 's/^ const tree = new Map(\[\[ctx.project, ctx.view\]\]);/ const tree = (ctx.tree = new Map([[ctx.project, ctx.view]]));/' $T
run missing-done-root-bucket $S 's/doneBucket(ctx.tree.get(project))/doneBucket(ctx.view)/' $T
run leave-tree-no-keep-updated $S '/} else if (!ctx.tree.has(project)) {/{n;s/ updated = c.updated;//}' $T
# Round 2: Dewey's three test gaps (comment 27280), under Dewey's names. Dewey's edits may differ.
# tick-done-root-bucket has two lines on the tick path: a closed task the cursor returns that the
# board no longer shows, and one the board still showed.
run reconcile-done-root-bucket $S 's/const bucket = t.done ? doneBucket(view) :/const bucket = t.done ? doneBucket(ctx.view) :/' $T
run tick-done-root-bucket $S "s/bucket: doneBucket(view), via: 'cursor'/bucket: doneBucket(ctx.view), via: 'cursor'/" $T
run tick-done-root-bucket-board $S 's/const b = use.done ? doneBucket(view) : bucket;/const b = use.done ? doneBucket(ctx.view) : bucket;/' $T
run tree-check-before-moved $S 's/ if (x.json.project_id !== project) {/ if (x.json.project_id !== project \&\& ctx.tree.has(project)) {/' $T
# Round 3: R2 (Filbert) and B1 (Dewey), the confirm read. Dewey's name for the 401 one.
run r3-no-confirm $S "s|^ const r = await ctx.sync('GET', \`/projects/\${project}\`);| const r = { status: 404 };|" $T
run r3-confirm-403-only $S 's/ return r.status === 403 || r.status === 404;/ return r.status === 403;/' $T
run r3-confirm-404-only $S 's/ return r.status === 403 || r.status === 404;/ return r.status === 404;/' $T
run r3-confirm-not-200 $S 's/ return r.status === 403 || r.status === 404;/ return r.status !== 200;/' $T
run r2-unauthorized-drops $S "s/ \&\& e.code !== 'tracker-not-found')) return false;/ \&\& e.code !== 'tracker-not-found' \&\& e.code !== 'tracker-unauthorized')) return false;/" $T
git diff --quiet -- $S $U packages/cli/src/config.mjs && echo "restored: sources match the candidate index"