refactor(probes): flatten the watch collapse and correct its comments - #8701
Conversation
Design Review (Fable 5) — ✅ PASSDesign-level review of All claims verified against the code: Design-Verdict: PASS A correctly-scoped, behavior-preserving hygiene sweep whose corrected docstrings now match the code they sit above; no design-level concerns. [DESIGN-REVIEWED] 5d0d960 |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — ✅ PASSPremise-level review of All claims verified against the code. Writing the review. First-Principles-Verdict: PASS A comment sweep that checked its own claims: both corrected docstrings now match the arbitration code they sit on, and every structural item is declared and behavior-free. What this change shipsIntent: make the probes module's comments truthful and its code flat, with no behavior change — a FIX (two false comments) plus a declared hygiene/simplification sweep.
No undeclared items, no new public surface, no config keys, no behavior. The corrected docstring's behavior is already pinned by [FIRST-PRINCIPLES-REVIEWED] 5d0d960 |
d37bbf1 to
9c6098c
Compare
Confirmed, and it is the same class of error this PR exists to remove — I replaced one overclaiming comment with another. Verified against GitHub's own schema as this repo spells it in The docstring now reads:
I took the fix one step wider than the finding asked, because the same overclaim had a sibling: |
The three red checks are inherited from
|
The pr-watch probe and its target inference carried rationale written as a
review log: a PR number, a review-round marker, a scanner attribution, and
past-tense narration about how each rule reached its current shape. Per
AGENTS.md a comment states current behavior and its reason, so each is restated
in present tense and the citations are dropped. Every rewritten claim was
checked against the adjacent code, which turned up two comments that were
already false:
- `_collapse`'s docstring ended "a missing ``startedAt`` sorts oldest", but a
row with no timestamp is not sorted at all: when either row is undated,
recency cannot arbitrate and the more conservative bucket wins, so an undated
failing row beats a dated passing one however new that date is. The docstring
pointed the wrong way on the one axis that matters here -- whether a
possibly-broken row can be swallowed by a green one -- and contradicted
`_CONSERVATIVE`'s own note 50 lines above. Both now say what makes a row
undated: a queued rerun has no `startedAt` yet, and a StatusContext carries
`createdAt` and never has one at all, so an absent start time is not evidence
of staleness. `_CONSERVATIVE`'s "must not lose to an OLDER all-good row" is
corrected the same way -- that branch reads no dates.
- `_PR_SHORTHAND`'s bound was explained as needed because the pattern "reads the
whole instruction rather than stopping at a match". It is the URL loop that
runs to completion; the shorthand loop returns on the first differing match.
The claim is dropped and the cross-reference to the URL pattern's own
explanation is kept.
Three structural simplifications, all behavior-preserving:
- `_collapse` unpacks the stored `(started, bucket)` pair into named locals
instead of reading `prev[0]` / `prev[1]`, and returns early on the first-row
case, so the recency-versus-conservativeness arbitration reads as one flat
chain. `parsed.path.strip("/")` is computed once instead of twice.
- `_bucket`'s pending vocabulary becomes the module constant `_PENDING`,
matching `_FAILING` / `_PASSING` / `_NOISE` rather than an inline tuple.
- `infer` parses a bare chain number the way its two sibling int parses already
do -- assign inside the `try`, compare after it -- which drops one nesting
level. `int()` is the only ValueError source there, so the guarded region is
unchanged.
`PrWatchProbe` also declares `host`, which `identity()` assigns and `_fetch()`
reads but the attribute block omitted, and `infer` builds its probe config as
one dict literal.
9c6098c to
5d0d960
Compare
dwu96
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: refactor (2 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: behaviour-preserving refactor of the check-rollup collapse — pending-conclusion set extracted to a named constant, the duplicate-row arbitration rewritten as an early-continue with unpacked locals (identical branch outcomes), a repeated path.strip() hoisted, the int() parse in the bare-PR scan lifted out of the comparison (same semantics), an adjacent-literal regex joined, and one dict entry moved into its literal; the only other addition is the missing host attribute annotation on PrWatchProbe, which is annotation-only on a plain class (not a dataclass) whose self.host assignment already exists on main. No control-flow or output change.
Problem / Motivation
src/kiro_crew/probes/had never been through the module-simplification sweep, and ithad accumulated the two things that sweep exists to remove.
Comments written as a review log.
gh_pr.pyandtargets.pyexplained their ownrules with a PR number (
#7665), a review-round marker (Round 23 deleted this pattern outright), a scanner attribution (this is the one CodeQL flagged), a finding count(
produced three separate review findings), and past-tense narration about how eachrule reached its current shape.
AGENTS.md§ Code style forbids all of these: a commentstates current behavior and its reason, and that history lives in git.
Two comments that were simply false — found by checking every rewritten claim against
the adjacent code rather than trusting the prose, which is the part of this work that is
not cosmetic:
_collapse's docstring ended "a missingstartedAtsorts oldest". A row with notimestamp is not sorted at all: when either row is undated the recency compare is
skipped and the more conservative bucket wins, so an undated
failingrow beats adated
passingone — verified against a2099timestamp. The docstring pointed thewrong way on the one axis that matters for a watch probe (whether a possibly-broken
row can be swallowed by a green one) and contradicted
_CONSERVATIVE's own note 50lines above.
_CONSERVATIVE's "must not lose to an older all-good row" iscorrected the same way: that branch reads no dates, so
olderwas aspirational._PR_SHORTHAND's quantifier bound was justified because the pattern "reads the wholeinstruction rather than stopping at a match". It is the URL loop that runs to
completion (it cannot know whether a second subject exists without seeing them all);
the shorthand loop
return Nones on the first differing match.Why it matters
A stale comment flipped to confident present tense misleads the next reader worse than
the stale one did, so a comment sweep that does not verify its claims makes things worse.
Both false comments are about how a red check can be suppressed — exactly the reasoning a
maintainer would lean on when changing this arbitration, and exactly where being wrong is
expensive.
AUTOSDE.yaml'srecurring-defect-patternsnames "a docstring or comment thatCONTRADICTS the code below it" as a class that has shipped as a bug here before.
What changed (motivation → approach → change)
Backend-only, two files, no behavior change anywhere.
Comment hygiene — six task-log citations dropped, the surviving rationale restated in
present tense, and the two false claims above corrected. For each removal I checked
whether a constraint a future editor needs went with the provenance; none did (e.g. the
#7665paragraph's load-bearing part — do not coercewake_on_greenfrom a string,because
bool("false")isTrue— survives verbatim beside the validator).Three structural simplifications:
_collapseunpacks the stored(started, bucket)pair intoprev_started/prev_bucketinstead of readingprev[0]/prev[1], and returns early on thefirst-row case, so the recency-versus-conservativeness arbitration reads as one flat
chain.
parsed.path.strip("/")is computed once instead of twice._bucket's pending vocabulary becomes the module constant_PENDING, matching_FAILING/_PASSING/_NOISErather than an inline tuple literal.inferparses a bare chain number the way its two sibling int parses already do —assign inside the
try, compare after it — dropping one nesting level.int()is theonly
ValueErrorsource there, so the guarded region is unchanged.Plus two accuracy fixes:
PrWatchProbenow declareshost, whichidentity()assignsand
_fetch()reads but the attribute block omitted; andinferbuilds its probe configas one dict literal instead of a literal followed by
config["host"] = …(which alsoremoves the window where the config exists without its host pin).
Deliberately not done, so a reviewer can see they were considered:
acp/client.py, a different module. One module per PR.hostin the module docstring's "Message format" block. It is a realvalidated message key, but the code comment at its parse site says it is expressly not
a configuration point — only
targets.infersets it, to one constant. Listing it in anoperator-facing format block would contradict that.
Target.host_key's"default"value is currently unreachable (inferis the onlyconstructor and always passes the public host). Removing the default changes a
constructor contract, which is a design call for the second probe kind, not a comment
sweep.
test/test_probe_targets.py's own docstring still carries the CodeQL attributionand first-person narration this PR removed from the code. Real, but it is a different
file this PR does not otherwise touch — a "while I'm here" fix belongs in its own PR.
_PR_URL's ReDoS rationale (targets.py:32-36) claims an unbounded+there is apolynomial shape; measurement did not reproduce that as quadratic, because the literal
httpprefix search rejects most start positions first. Unchanged by this PR and leftalone: correcting it means re-deciding why those bounds exist, which is wider than this
diff.
Tests
No test changes — this PR adds no behavior to lock in, and a test asserting a comment's
text would be the wrong instrument. Existing coverage already pins what the corrected
docstring now describes:
test_babysit_pr_watch.py::test_queued_rerun_without_timestamp_blocks_false_readyasserts that an undated rerun row must not lose to an older green row and produce a false
all-green wake — i.e. the behavior the old docstring described backwards.
167 tests across
test_babysit_pr_watch.py,test_probe_targets.py,test_babysit_guidance_gates.pyandtest_irq.pypass, plus the 824 in the widertest_irq/test_autonudge*/test_monitor_*/test_github_pull_request_monitorset.Manual verification
N/A — unit coverage sufficient, and equivalence was established mechanically rather than
by inspection:
_collapse: exhaustive differential over all 1,884 possible 1–3-row input sequences(3 timestamp values × 4 buckets), pre-diff vs post-diff — 0 divergences. Independently
reproduced by a reviewer at 40,000 and 60,000 randomized rollups (mixed workflow-less
rows, 15
detailsUrlshapes, non-dict rows, missingstartedAt), compared as orderedlists to catch dict-insertion-order drift — 0 diffs.
_bucket: exhaustive over 1,080 and 3,174conclusion × state × statuscombinationsincluding
None/""/0/False/ lowercase / unknown vocabulary — 0 diffs, andnothing moved between
pendingandfailingin either direction.infer: 200,000 and 60,000 randomized instruction texts built from adversarialfragments (bare chains,
&/and/comma separators, path fragments, enterprise hosts, a4,400-digit number that trips CPython's int-conversion limit,
#0,#007), comparing(kind, subject, host_key, message)withmessagebyte-wise — 0 diffs."host"presenton every one of 6,685 non-
Noneresults, and the set of host values ever written isexactly
{'github.com'}..patternand.flagscompared at runtime — byte-identical,including
_PR_BARE, whose two adjacent string literals were already concatenated atparse time.
host: str:Probeis a plain class (no@dataclass, no__slots__, no metaclass,no
__init_subclass__), so a bare annotation creates no class attribute —hasattr(PrWatchProbe, "host")isFalseboth before and after, and nothing in the reporeflects over these annotations.
Gates, all exit 0 on the rebased head:
flake8,isort --check-only,mypy --platform linux,black --check(both touched files),check_brand_name.py,check_harness_parity.py,check_black_formatting.py,check_changelog_history.py,check_per_file_coverage.py --test,docs_lint.py --test,docs-lint.sh,verify_vendor_manifest.py,scrub-lint.sh --no-history, and the deterministiccode-review.ymlgrep rules (sensitive-path reads, hardcoded model literals, inclusivelanguage on added lines) — no matches.
Blocked by a red
main, not by this diffBackend Tests (3.12, 3),Backend Tests (Windows) (3)andCoverage Gateare red onthis PR and cannot be made green from here. They are inherited from
main:test/test_push_branch_gate.pyandtest/test_security.py(
TestGitPublishSubshellGluing,TestUnrecognisedOptionsReadProtectively) — thegit-publish shell-word gate. This PR touches only two modules under
src/kiro_crew/probes/and no security file.origin/main(
6d1b51704) fails the identical 9 tests — the failure setsdiffclean against thisbranch's. Bisected to
eaa8a45bb"fix(security): model publish option arity so thefloor tag holds (fix(security): model publish option arity so the floor tag holds #7808)": its parent passes 1936 tests, the commit itself fails 9.
Coverage Gateis the same single failure, not a second one — shard 3 aborted, so itproduced no coverage data to gate on.
naming
#7808as cascading to every PR.The two shard-3 jobs on this PR's head report the same nine test ids that pristine
origin/maindoes — the setsdiffclean, so zero failures are attributable to this PR.I did not touch it.
security.pyis a keystone security file that the simplificationcampaign forbids reshaping, and folding an unrelated security-gate repair into a
comment-and-readability PR is precisely the "undocumented bug fix riding in a cleanup PR"
this work exists to avoid. This PR is otherwise green — 52 of the 55 non-skipped checks
pass, including all five review lanes with zero findings between them — and it will go
green on its own once
#7808is fixed or reverted onmainand this branch is rebased.Screenshots / video
Why no screenshot: backend-only diff — two Python modules under
src/kiro_crew/probes/,nothing under
website/, so no rendered surface changes and CI reportsonly_backend.Related Issues
no linked issue: routine module-simplification sweep, not a tracked defect.
Checklist