Packet agents/rocko/work/queue-79/ (packet manifest b6b11e7b, 42 files, candidate manifest 16b12387), Rocko's BUILD-LOG and SESSIONS appends. Committed by Sage for Rocko, who has no credential. Co-Authored-By: Claude Opus 5.5 <[email protected]>
112 lines
5.7 KiB
Diff
112 lines
5.7 KiB
Diff
diff --git a/agents/rocko/work/queue-79/mutants.sh b/agents/rocko/work/queue-79/mutants.sh
|
|
new file mode 100755
|
|
index 00000000..0d925699
|
|
--- /dev/null
|
|
+++ b/agents/rocko/work/queue-79/mutants.sh
|
|
@@ -0,0 +1,45 @@
|
|
+#!/usr/bin/env bash
|
|
+# Row 79 (#1573): rerun the untyped-list mutants against a tree. Usage:
|
|
+# mutants.sh <tree>. Each mutant edits untypedActions in
|
|
+# packages/harness/src/tools.mjs, runs the harness tools test, and restores
|
|
+# the file from a saved copy, so the tree need not be committed. Prints
|
|
+# "killed" or "SURVIVED" per mutant; exit 1 if any survives, a sed doesn't
|
|
+# change the file, or the unmutated run fails. untyped-within-only stands in
|
|
+# for Dewey's mutant of that name (row 73 comment 27506).
|
|
+set -euo pipefail
|
|
+TREE="$(cd "${1:?usage: mutants.sh <tree>}" && pwd)"
|
|
+cd "$TREE"
|
|
+SRC=packages/harness/src/tools.mjs
|
|
+TESTS=(packages/harness/tests/tools.test.mjs)
|
|
+run_tests() { node --test "${TESTS[@]}" >"$1" 2>&1; }
|
|
+
|
|
+# name | sed expression
|
|
+MUTANTS=(
|
|
+ 'untyped-within-only|s/^ return \[\.\.\.resolved\.limits\.authority\.withinRole, \.\.\.resolved\.limits\.authority\.crossRole\]\.filter/ return [...resolved.limits.authority.withinRole].filter/'
|
|
+ 'untyped-cross-first|s/^ return \[\.\.\.resolved\.limits\.authority\.withinRole, \.\.\.resolved\.limits\.authority\.crossRole\]\.filter/ return [...resolved.limits.authority.crossRole, ...resolved.limits.authority.withinRole].filter/'
|
|
+ 'untyped-keeps-typed|s/\.filter((a) => !typed\.has(a));$/.filter((a) => a === "message.send" || !typed.has(a));/'
|
|
+)
|
|
+
|
|
+OUT="${OUT:-$TREE/.mutants}"
|
|
+mkdir -p "$OUT"
|
|
+run_tests "$OUT/baseline.log" || { echo "baseline run failed: $OUT/baseline.log" >&2; exit 1; }
|
|
+echo "baseline: pass"
|
|
+status=0
|
|
+for m in "${MUTANTS[@]}"; do
|
|
+ IFS='|' read -r name expr <<<"$m"
|
|
+ cp -p "$SRC" "$OUT/orig"
|
|
+ sed -i -e "$expr" "$SRC"
|
|
+ if cmp -s "$OUT/orig" "$SRC"; then
|
|
+ echo "$name: NOT APPLIED (sed matched nothing)"; status=1; continue
|
|
+ fi
|
|
+ diff -u "$OUT/orig" "$SRC" >"$OUT/$name.diff" || true
|
|
+ if run_tests "$OUT/$name.log"; then
|
|
+ echo "$name: SURVIVED"; status=1
|
|
+ else
|
|
+ echo "$name: killed ($(grep -E '^✖' "$OUT/$name.log" | grep -v 'failing tests' | sed 's/ ([0-9.]*ms)$//' | sort -u | tr '\n' ';'))"
|
|
+ fi
|
|
+ cp -p "$OUT/orig" "$SRC"
|
|
+ cmp -s "$OUT/orig" "$SRC" || { echo "restore failed: $SRC" >&2; exit 1; }
|
|
+ rm -f "$OUT/orig"
|
|
+done
|
|
+exit "$status"
|
|
diff --git a/packages/business/README.md b/packages/business/README.md
|
|
index 9c3e8d1f..ca372c5e 100644
|
|
--- a/packages/business/README.md
|
|
+++ b/packages/business/README.md
|
|
@@ -34,7 +34,7 @@ in this repository, or `$MOSAIC_ROLES_DIR` if set.
|
|
"network": "api-only",
|
|
"authority": {
|
|
"withinRole": ["task.update.assigned", "git.push.working", "review.request", "message.send"],
|
|
- "crossRole": ["task.reassign", "task.scope.change"]
|
|
+ "crossRole": ["task.scope.change"]
|
|
},
|
|
"credentials": [
|
|
{ "service": "gitea", "scopes": ["write:issue", "write:repository", "read:user"] },
|
|
diff --git a/packages/harness/tests/tools.test.mjs b/packages/harness/tests/tools.test.mjs
|
|
index 31606131..3fe7dd1e 100644
|
|
--- a/packages/harness/tests/tools.test.mjs
|
|
+++ b/packages/harness/tests/tools.test.mjs
|
|
@@ -30,9 +30,7 @@ test("a coder gets no launch, no resolve_decision, and no task tools without a t
|
|
const tools = typedTools({ resolved: coder });
|
|
assert.deepEqual(names(tools), ["send_message", "raise_decision", "list_agents", "inbox", "trail"]);
|
|
// Held actions without a tool are listed, so the manifest shows them.
|
|
- const untyped = untypedActions(coder, tools);
|
|
- assert.ok(untyped.includes("git.push.working"));
|
|
- assert.ok(!untyped.includes("message.send"));
|
|
+ assert.deepEqual(untypedActions(coder, tools), ["task.update.assigned", "git.push.working", "review.request", "task.scope.change"]);
|
|
});
|
|
|
|
test("a coder with a tracker gets its own task tools and no task_reassign", (t) => {
|
|
diff --git a/packages/tasks/README.md b/packages/tasks/README.md
|
|
index 61b36664..d47f5de6 100644
|
|
--- a/packages/tasks/README.md
|
|
+++ b/packages/tasks/README.md
|
|
@@ -190,10 +190,10 @@ Details that aren't obvious from the table:
|
|
- `task.close` moves the task into the done bucket. `verdict` is a
|
|
citation of the review verdict in the queue. The adapter records it
|
|
and doesn't check it. Checking it against the queue is a follow-up.
|
|
-- A coder role's `crossRole` grant of `task.reassign` can't be used. The
|
|
- writer check refuses it before authority is looked at. If a coder
|
|
- should hand work on, that's a change to the field table, not to the
|
|
- role file.
|
|
+- The coder role holds no `task.reassign` grant (row 73). The writer
|
|
+ check refuses a non-pm `task.reassign` before authority is looked at
|
|
+ anyway. If a coder should hand work on, that's a change to the field
|
|
+ table, not to the role file.
|
|
|
|
Verbs for one business run one at a time, in the same queue as the poll,
|
|
so a poll never reads between two writes of a verb.
|
|
diff --git a/packages/tasks/live/run.mjs b/packages/tasks/live/run.mjs
|
|
index eed1513e..0c8d7e97 100644
|
|
--- a/packages/tasks/live/run.mjs
|
|
+++ b/packages/tasks/live/run.mjs
|
|
@@ -29,7 +29,7 @@ const AUTHORITY = {
|
|
withinRole: ['task.create', 'task.assign', 'task.reassign', 'task.schedule', 'task.update.assigned', 'task.close', 'message.send'],
|
|
crossRole: ['task.priority.change', 'task.scope.change'],
|
|
},
|
|
- coder: { withinRole: ['task.update.assigned', 'message.send'], crossRole: ['task.reassign', 'task.scope.change'] },
|
|
+ coder: { withinRole: ['task.update.assigned', 'git.push.working', 'review.request', 'message.send'], crossRole: ['task.scope.change'] },
|
|
reviewer: { withinRole: ['task.update.assigned', 'message.send'], crossRole: [] },
|
|
};
|
|
const ref = (x) => (x.file ? { file: x.file, expires: x.expires } : { env: x.env, expires: x.expires });
|