forked from heavy-duty/ceremony
fix: refuse a bracket login that is not [A-Za-z0-9-] — round 1, codex
panel[z]]=b parsed at the round-1 head: the case pattern only proves some ]= occurs, so the stray ] stayed inside the login and the real author silently fell back to the base panel — the misroute D4 exists to refuse. The login charset is now enforced with the bracket-specific diagnostic; codex's probe and an invalid-character row are the new must-fail fixtures. Refs #224 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6f245639ca
commit
069faf481a
2 changed files with 35 additions and 1 deletions
|
|
@ -187,6 +187,18 @@ parse_panel_author_row() { # panel[<login>]=<space-separated logins> (#224)
|
|||
echo "labels: empty login in panel row: $line in $conf" >&2
|
||||
return 1
|
||||
}
|
||||
# The login must be exactly one well-formed bracket pair of login
|
||||
# characters. Without this, panel[z]]=b parses: the case above only
|
||||
# establishes that SOME ]= occurs, ${login%%]=*} keeps the stray ] inside
|
||||
# the login (z]), and set_required_bots for the real z then silently falls
|
||||
# back to the base panel — the misroute D4 exists to refuse. GitHub logins
|
||||
# are [A-Za-z0-9-], per the #285 spec.
|
||||
case "$login" in
|
||||
*[!A-Za-z0-9-]*)
|
||||
echo "labels: malformed panel[<login>]= row (a login is [A-Za-z0-9-] only): $line in $conf" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
for existing in ${PANEL_AUTHORS[@]+"${PANEL_AUTHORS[@]}"}; do
|
||||
[ "$existing" != "$login" ] || {
|
||||
echo "labels: duplicate panel[$login]= row in $conf: $line" >&2
|
||||
|
|
@ -504,6 +516,20 @@ decide_state() { # → the one state:* label this PR should carry
|
|||
local s
|
||||
s="$(round_state)"
|
||||
|
||||
# A draft disqualifies needs-human unconditionally (#205, round 1): with
|
||||
# the short-circuit above now conditional, a draft carrying a live human
|
||||
# request plus a standing bot block or comment fell through to
|
||||
# round_state, whose explicit-human-request precedence sits above the
|
||||
# BLOCK/FEEDBACK cases — and GitHub cannot merge a draft at all, so
|
||||
# "a human could merge this right now" would lie no matter what the
|
||||
# round says. state:addressing is the same honest landing the blocker/
|
||||
# needs-ruling/blocked clauses below use: the round's word stands, only
|
||||
# the mergeable-now claim is off the table while the PR is a draft.
|
||||
if [ "$s" = state:needs-human ] && [ "$DRAFT" = true ]; then
|
||||
echo state:addressing
|
||||
return
|
||||
fi
|
||||
|
||||
# The one rule joining the two axes: state:needs-human means a human could
|
||||
# merge this RIGHT NOW, so it requires a clear branch. Any blocker at all
|
||||
# means the work is the agent's — whatever the review round says — and the
|
||||
|
|
@ -606,7 +632,7 @@ round_state() { # → the state the REVIEW ROUND alone implies; knows no branch
|
|||
|
||||
core_label_rows() {
|
||||
cat <<'EOF'
|
||||
state:building|FBCA04|PR is a draft — the coding agent is still building
|
||||
state:building|FBCA04|Pre-round: the builder is still building — draft is evidence for it, not the definition
|
||||
state:bots-reviewing|1D76DB|Waiting on the bot reviewers to finish the round
|
||||
state:addressing|D93F0B|All bots reviewed — coding agent owes the single reply + fixes
|
||||
state:needs-human|8250DF|No blockers, all bots approve — waiting on the human reviewer
|
||||
|
|
|
|||
|
|
@ -96,6 +96,14 @@ check "a bracketed row naming zero reviewers fails loudly" 1 \
|
|||
printf '%s\n' 'panel=a b c' 'panel[]=b c' >"$TMP/empty-login.conf"
|
||||
check "an empty login fails loudly" 1 "empty login in panel row" \
|
||||
load_config "$TMP/empty-login.conf"
|
||||
# codex's round-1 probe: the stray ] used to parse, record login z], and
|
||||
# silently misroute z to the base panel — exactly the D4 refusal owed.
|
||||
printf '%s\n' 'panel=a b c' 'panel[z]]=b' >"$TMP/stray-bracket.conf"
|
||||
check "a stray ] inside the bracket is refused as a bracket" 1 \
|
||||
"malformed panel[<login>]= row" load_config "$TMP/stray-bracket.conf"
|
||||
printf '%s\n' 'panel=a b c' 'panel[a_b]=c' >"$TMP/bad-login.conf"
|
||||
check "a non-login character in the bracket is refused" 1 \
|
||||
"malformed panel[<login>]= row" load_config "$TMP/bad-login.conf"
|
||||
printf '%s\n' 'panel=a b c' 'panel[z=b c' >"$TMP/broken-bracket.conf"
|
||||
check "a malformed bracket is refused as a bracket (D4)" 1 \
|
||||
"malformed panel[<login>]= row" load_config "$TMP/broken-bracket.conf"
|
||||
|
|
|
|||
Loading…
Reference in a new issue