roles: drop the coder's stale task.reassign text, pin the untyped list (#1573)

Row 79 round 1, owner Rocko, candidate manifest 16b12387 on 331d037c.
Approved by Dewey (27611); Sage's gate green.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-11 20:23:35 -05:00
co-authored by Claude Opus 5.5
parent 29124395f4
commit 3780e05df7
4 changed files with 7 additions and 9 deletions
+4 -4
View File
@@ -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.
+1 -1
View File
@@ -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 });