test(issueflow): the evidence nudge's fixtures — window, addressee, no marker
Covers the must-nudge pair (8 quiet days; post-merge + needs-ruling both speak), the must-not set (6 days, fresh comment, every other queue state), self-rate-limiting proven by sweeping again a day later rather than by asserting a marker's absence, and zero writes across every probe. Two existing probes move: #36's 'no comment' assertion described the starvation this issue ends, and #67 gets recent activity so its precedence count stays the assertion doing the work. Refs #254
This commit is contained in:
parent
63351bd425
commit
b3fd26b21b
1 changed files with 130 additions and 2 deletions
|
|
@ -431,7 +431,11 @@ issue_probe() { # $1 issue, $2 labels, $3 assignees, $4 false|closing|refs, $5 m
|
|||
local assignees="${3:-1}" open_pr="${4:-false}" merged_ref_prs="${5:-}"
|
||||
local body="${6:-}" assignee_json='[]' open_pr_records="" spec pr merged_at
|
||||
[ "$assignees" -eq 0 ] || assignee_json='[{"login":"owner-bot"}]'
|
||||
REPO=owner/repo NOW="$INOW"
|
||||
# `PROBE_NOW` moves the sweep's clock without moving the fixtures — the
|
||||
# only way to prove a rule that self-rate-limits on its own comment's
|
||||
# timestamp (#254): sweep, then sweep again a day later and watch the
|
||||
# nudge stay silent because the comment it posted is now the activity.
|
||||
REPO=owner/repo NOW="${PROBE_NOW:-$INOW}"
|
||||
ISSUE_LABELS="$2"
|
||||
ISSUE_JSON="$(jq -n --arg at "$(iso_at $((INOW - 10 * 86400)))" \
|
||||
--argjson assignees "$assignee_json" --arg body "$body" \
|
||||
|
|
@ -517,6 +521,13 @@ check "...drawing the #252 parse echo and nothing else" 0 "1" \
|
|||
grep -c -- '^----$' "$TMP/posted-66"
|
||||
|
||||
attention_episode 67 "$(iso_at $((INOW - 60)))"
|
||||
# Recent activity keeps the evidence nudge (#254) off this probe: it is a
|
||||
# precedence case, and "exactly one comment" is the assertion doing the work.
|
||||
# The nudge's own coexistence with the post-merge diagnostic is pinned in its
|
||||
# section below, on a probe that is quiet on purpose.
|
||||
jq -n --arg at "$(iso_at $((INOW - 60)))" \
|
||||
'[{"user":{"login":"triage-one"},"created_at":$at,"html_url":"https://x/c67","body":"still waiting on the tag"}]' \
|
||||
>"$(cfix 67)"
|
||||
post_merge_attention="$(issue_probe 67 $'post-merge\nattention' 0)"
|
||||
check "post-merge precedence leaves exactly its existing comment" 0 "1" \
|
||||
grep -c -- '^----$' "$TMP/posted-67"
|
||||
|
|
@ -617,7 +628,13 @@ printf '[]\n' >"$(cfix 36)"
|
|||
post_merge_quiet="$(issue_probe 36 post-merge 0)"
|
||||
check "quiet unassigned post-merge work is not reclaimed" 1 "" \
|
||||
grep -q 'reclaimed' <<<"$post_merge_quiet"
|
||||
check "...and causes no comment or edit" 1 "" test -f "$TMP/posted-36"
|
||||
# The quiet itself is now visible (#254) — this probe is 10 days old with no
|
||||
# activity, so it draws the evidence nudge and nothing else. It used to
|
||||
# assert no comment at all; that assertion described the starvation this
|
||||
# issue exists to end, and the edit half of it is what still matters.
|
||||
check "...and causes no edit" 1 "" grep -qF -- 'issue edit 36' "$TMP/issue-edits"
|
||||
check "...only the evidence nudge speaks" 0 "1" \
|
||||
grep -c -- '^----$' "$TMP/posted-36"
|
||||
|
||||
printf '[]\n' >"$(cfix 37)"
|
||||
issue_probe 37 post-merge 1 >/dev/null
|
||||
|
|
@ -625,6 +642,117 @@ check "assigned post-merge is flagged" 0 "" \
|
|||
grep -qF '<!-- issueflow:post-merge-assigned -->' "$TMP/posted-37"
|
||||
check "...and the hand-assignment is not repaired" 1 "" \
|
||||
grep -qF -- 'issue edit 37' "$TMP/issue-edits"
|
||||
# The flag and the nudge answer different questions — a board bug and a
|
||||
# starved wake condition — so neither suppresses the other (#254).
|
||||
check "...and the evidence nudge rides beside it, neither suppressed" 0 "2" \
|
||||
grep -c -- '^----$' "$TMP/posted-37"
|
||||
|
||||
# -- the post-merge evidence nudge (#254), the ruling nudge's twin ----------
|
||||
# The ruling nudge solved "a wait goes quiet and nobody is told" for
|
||||
# `needs-ruling`; `post-merge` had no equivalent, and crew#181's real-host
|
||||
# criterion starved four times across two releases for want of one. Same
|
||||
# 7-day constant (`ruling_nudge_decision`, reused not mirrored), same
|
||||
# deliberate absence of an idempotency marker, and — unlike the ruling
|
||||
# nudge — addressed to the triage actor, because `post-merge` is triage's
|
||||
# completion queue and the operator owes nothing here (#254 D1).
|
||||
nudge_edits_before="$(wc -l <"$TMP/issue-edits")"
|
||||
|
||||
quiet_comment() { # $1 issue, $2 seconds of quiet — one ordinary comment, then silence
|
||||
jq -n --arg at "$(iso_at $((INOW - $2)))" \
|
||||
'[{"user":{"login":"triage-one"},"created_at":$at,"html_url":"https://x/c","body":"evidence pending"}]' \
|
||||
>"$(cfix "$1")"
|
||||
printf '[]\n' >"$(tfix "$1")"
|
||||
}
|
||||
|
||||
quiet_comment 80 $((8 * 86400))
|
||||
nudged="$(issue_probe 80 post-merge 0)"
|
||||
check "8 quiet days on a post-merge item draws the evidence nudge" 0 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$nudged"
|
||||
# shellcheck disable=SC2016 # expansions belong to the isolated bash -c process
|
||||
check "...addressed to the triage actor, never the human reviewer" 0 "" \
|
||||
bash -c 'grep -qF "@triage-one" "$1" && ! grep -qF "@danmt" "$1"' _ "$TMP/posted-80"
|
||||
check "...with the issue link as the payload" 0 "" \
|
||||
grep -qF 'https://github.com/owner/repo/issues/80' "$TMP/posted-80"
|
||||
check "...carrying the do-not-add-a-marker warning in the comment" 0 "" \
|
||||
grep -qF 'Do not add a marker.' "$TMP/posted-80"
|
||||
# Asserted directly, not merely omitted: a marker would turn "once per 7
|
||||
# quiet days" into "once per issue, forever" — the exact "fix" lib/ruling.sh's
|
||||
# header records as the thing that breaks this rule.
|
||||
check "...and no idempotency marker on the path" 1 "" \
|
||||
grep -qF '<!-- issueflow:' "$TMP/posted-80"
|
||||
|
||||
# Self-rate-limiting, proven by the property and not by the mechanism: sweep
|
||||
# again a day later, against fixtures the first sweep's own comment mutated.
|
||||
nudged_again="$(PROBE_NOW=$((INOW + 86400)) issue_probe 80 post-merge 0)"
|
||||
check "a sweep one day after the nudge holds its silence" 1 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$nudged_again"
|
||||
check "...so exactly one nudge exists across both sweeps" 0 "1" \
|
||||
grep -c -- '^----$' "$TMP/posted-80"
|
||||
|
||||
quiet_comment 81 $((6 * 86400))
|
||||
six_days="$(issue_probe 81 post-merge 0)"
|
||||
check "6 quiet days is inside the window and draws nothing" 1 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$six_days"
|
||||
check "...and posts no comment at all" 1 "" test -f "$TMP/posted-81"
|
||||
|
||||
# Label churn is not activity, or the sweep resets its own clock. The rule is
|
||||
# `last_issue_activity`'s, shared with the reclaim and ruling clocks rather
|
||||
# than restated here — this probe pins that the nudge inherits it.
|
||||
jq -n --arg at "$(iso_at $((INOW - 3600)))" \
|
||||
'[{"event":"labeled","label":{"name":"scope:docs"},"created_at":$at},
|
||||
{"event":"unlabeled","label":{"name":"scope:docs"},"created_at":$at}]' >"$(tfix 82)"
|
||||
printf '[]\n' >"$(cfix 82)"
|
||||
churn="$(issue_probe 82 post-merge 0)"
|
||||
check "an hour-old label churn does not reset the 7-day clock" 0 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$churn"
|
||||
|
||||
quiet_comment 83 3600
|
||||
fresh="$(issue_probe 83 post-merge 0)"
|
||||
check "an hour-old comment does reset it" 1 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$fresh"
|
||||
|
||||
# Both waits are quiet, both are owed, and to different parties: suppressing
|
||||
# one because the other spoke is a starved criterion, which is the failure
|
||||
# this nudge exists to remove.
|
||||
jq -n --arg l "$(iso_at $((INOW - 9 * 86400)))" \
|
||||
'[{"event":"labeled","label":{"name":"needs-ruling"},"actor":{"login":"setter"},"created_at":$l}]' \
|
||||
>"$(tfix 84)"
|
||||
jq -n --arg at "$(iso_at $((INOW - 9 * 86400 - 60)))" \
|
||||
--arg b $'Options: A — x B — y\nRecommend: A, because x.\nBlocked: z\nDefault: none — hard block' \
|
||||
--arg r12 "$(iso_at $((INOW - 9 * 86400 + 13 * 3600)))" \
|
||||
--arg r24 "$(iso_at $((INOW - 9 * 86400 + 25 * 3600)))" \
|
||||
'[{"user":{"login":"setter"},"created_at":$at,"html_url":"https://x/esc84","body":$b},
|
||||
{"user":{"login":"sweep-bot"},"created_at":$r12,"html_url":"https://x/r12","body":"<!-- ceremony:needs-ruling-rung12 -->\nrung"},
|
||||
{"user":{"login":"sweep-bot"},"created_at":$r24,"html_url":"https://x/r24","body":"<!-- ceremony:needs-ruling-rung24 -->\nrung"}]' \
|
||||
>"$(cfix 84)"
|
||||
both="$(issue_probe 84 $'post-merge\nneeds-ruling' 0)"
|
||||
check "a quiet post-merge item under a pending ruling nudges both waits" 0 "" \
|
||||
grep -q 'post-merge evidence nudge' <<<"$both"
|
||||
check "...and the ruling nudge is not suppressed by it" 0 "" \
|
||||
grep -q 'ruling nudge' <<<"$both"
|
||||
# shellcheck disable=SC2016 # expansions belong to the isolated bash -c process
|
||||
check "...each addressing its own party" 0 "" \
|
||||
bash -c 'grep -qF "@triage-one" "$1" && grep -qF "@danmt" "$1"' _ "$TMP/posted-84"
|
||||
|
||||
# Every other queue state: the nudge is `post-merge`'s alone. Each is equally
|
||||
# quiet, and `claimed` carries an open PR so its own reclaim clock — the one
|
||||
# other 10-day rule on this path — stays out of the way.
|
||||
non_post_merge=(85:ready:0:false 86:claimed:1:true 87:blocked:0:false 88:epic:0:false 89:needs-triage:0:false)
|
||||
for spec in "${non_post_merge[@]}"; do
|
||||
IFS=: read -r n state probe_assignees probe_pr <<<"$spec"
|
||||
printf '[]\n' >"$(cfix "$n")"
|
||||
printf '[]\n' >"$(tfix "$n")"
|
||||
check "a 10-day-quiet $state issue draws no evidence nudge" 1 "" \
|
||||
grep -q 'post-merge evidence nudge' \
|
||||
<<<"$(issue_probe "$n" "$state" "$probe_assignees" "$probe_pr")"
|
||||
done
|
||||
|
||||
# `post-merge` is the one queue state whose whole meaning is that the machine
|
||||
# owes nothing (LABELS.md: the sweep never reclaims it). This issue makes the
|
||||
# quiet visible; it must never make it actionable.
|
||||
# shellcheck disable=SC2016 # positional parameter belongs to the isolated shell
|
||||
check "the evidence-nudge probes perform no issue edits" 0 "$nudge_edits_before" \
|
||||
bash -c 'wc -l <"$1"' _ "$TMP/issue-edits"
|
||||
|
||||
# -- non-triggers stay byte-for-byte outside the transition ------------------
|
||||
recent_timeline() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue