Repository navigation
Description
Problem
Child of #793. Delivers the Go command: AC1 through AC11 of the parent. The consumer wrapper and the fallback belong to one sibling child, and the shell-parity proof belongs to #978.
On origin/main at a0347a715fab580ece45edfcb3d13509620459a8, watching remains shell behavior: target discovery and prerequisites at packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:53, snapshot reads and rerun selection at packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:82, appearance waiting at packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:106, streamed results at packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:128, and final judgement at packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:177.
The existing Go command evaluates saved rollups; it does not watch live checks (internal/agentrepo/command.go:40). Its input, rerun ordering and exit statuses differ from the watcher (docs/checks-evaluator.md:3, docs/checks-evaluator.md:9, docs/checks-evaluator.md:13). Moving the watcher must preserve its caller contract rather than substitute the saved-rollup contract.
Acceptance criteria
- AC1: Given an explicit PR number or the current branch's open PR,
agentrepo checks watchwatches the same target as the existing entry point; unavailable repository context, missing GitHub access, or no discoverable PR produces the existing refusal instead of starting a watch. - AC2: Given multiple attempts for a workflow/job pair, only its newest attempt by the existing run-link ordering contributes to the watched snapshot, independently of identically named jobs in other workflows.
- AC3: For each eligible settled check, the watcher promptly emits the existing one-line result, once per workflow/job pair during that watch, without waiting for slower unfinished jobs.
- AC4: Non-functional: watching changes no repository content, Git state or remote state.
- AC5: Given a final nonempty snapshot, the closing summary and status reflect that snapshot:
ALL GREENand 0 when it contains no failed or cancelled checks, otherwiseFAILEDwith the final failing count and status 1, even after a rerun replaces an earlier failure. - AC6: Given no registered checks, the watcher uses the existing appearance bound and finishes with
NO CHECKSand status 2 if none appear. - AC7: Given checks still unfinished at the settling bound, the watcher finishes with
TIMEOUTand status 2, preserving the existing interval and bound settings and defaults. - AC8: Given an ordinary failed check read, malformed JSON, a non-array response, or failed response processing, the watcher emits the existing
ERRORdiagnostic and exits 2 without reporting green. - AC9: Given quota exhaustion, the watcher stops with status 76 and the existing limit guidance and original error, without another request or an automatic retry.
- AC10: Non-functional: each check snapshot requires exactly one check read.
- AC11: Non-functional: the watcher produces the same observable outcomes on Linux, macOS and Windows.
Scope and non-goals
Moves into agentrepo checks: PR selection, watch prerequisites, snapshot acquisition, attempt selection, event suppression and streaming, appearance and settling waits, final reporting, and watcher-specific error/status handling.
The preserved contract includes:
| Behavior | Evidence on the pinned baseline |
|---|---|
| Repository-root execution and stable output despite locale, pager, prompts and repository-retargeting environment variables | packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:33 |
| Access check and optional current-branch discovery; discovery/access errors retain their existing statuses | packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:61 |
WATCHING start line; numeric run-link ordering within each workflow/job pair |
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:72, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:98 |
Literal no checks reported read failure is treated as an empty snapshot; other nonzero reads are errors except quota status 76 |
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:83 |
Appearance default 120 seconds with 5-second spacing; settling interval default 30 seconds and separate settling budget default 1800 seconds; existing PR_CHECKS_* overrides |
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:49, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:108, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:169 |
Existing sorted PASS, SKIP, FAIL and literal fallback-bucket lines; failure/cancellation links; displayed labels remain job names |
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:132, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:150 |
| Once-per-pair events, deferred cancellation, continued waiting after an early failure, final-state recount | packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:134, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:144, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:165, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:177 |
| Quota classification and original diagnostic preservation | packages/agents/source/lib/lib.sh:823, packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:87 |
Non-goals:
-
Workflow-qualified displayed labels (watch-checks.sh prints job names without their workflow, so same-named jobs look like duplicates #310), backoff or event-based waiting (watch-pr: default 30s poll interval multiplies across concurrent agents #370), accepting additional GitHub CLI exit statuses (watch-pr reports pending checks as unreadable because gh pr checks exits 8 #375), changing appearance guidance or messages (watch-pr ends with NO CHECKS after an undocumented 120-second bound that PR_CHECKS_TIMEOUT does not control #430), stalled-analysis classification (watch-pr names a stalled code-scanning analysis instead of reporting a generic timeout #465), and transient retries (watch-checks.sh retries a transient 5xx once before reporting ERROR #515). These are separate behavior changes; this child preserves the pinned baseline, including ordinary nonzero-read refusal.
-
Changing accepted bucket/run-link semantics, final-status policy, or the saved-rollup evaluator's input, output, ordering or statuses. The two existing contracts are distinct.
-
Porting the watching guard (
packages/agents/source/skills/watch-pr/claude/scripts/guard-watch.sh:42), changing how callers display the stream, fixing checks, publishing, or merging. These are outside the watcher command. -
Preserving a Go-path dependency on shell parsing tools or porting unrelated shared-library behavior. Required legacy dependencies remain part of the frozen fallback.
-
The consumer-facing shell wrapper, the probe, the frozen fallback and their tests: the sibling child delivers them with AC12.
-
Proving the command against the frozen shell on identical scripted responses: test(checks): prove watch command parity against the pinned shell #978 delivers it.
Approach
Establish the watcher contract from the pinned source and all nine cases in tests/skills/watch-pr/scripts/watch-checks.bats:41 before replacing behavior. Add missing behavioral coverage for events, cancellation, waits, discovery and prerequisites. Keep watcher behavior distinct from saved-rollup evaluation. The shell entry point stays unchanged in this child. Comparing the command with the frozen shell on identical scripted responses moves to #978, which builds on this one. All evidence that closes this child, including AC4 repository-state preservation, lands in this child's pull request (#961) and does not depend on #977 or #978.
Dependencies
- Parent: feat(checks): move pull request watching into Go #793.
- Port the shared skill library (lib.sh, agent.sh, signing.sh, gates.py) to Go #321: shared GitHub access and quota behavior used by the watcher.
- feat(checks): assess saved pull request check summaries #242: the saved-check evaluator, whose published contract stays as it is.
- The sibling wrapper child and test(checks): prove watch command parity against the pinned shell #978 depend on this one.
Size
M
Verify plan
- Failing test first: add command-level regressions that fail because the Go watcher is absent, then make them pass against the Go command alone. Use scripted local responses and controlled time; no live PR watching is needed.
- AC1: Exercise explicit and inferred targets, root and nested invocation, absent repository/PR/access, missing prerequisites, and retargeting environment values; assert target, refusal streams and status against the pinned source.
- AC2: Replay old failure/new success in one pair and independent same-named jobs in two workflows; reverse input order and assert only the baseline-selected attempts affect the result. Include the existing run-link edge cases in fixtures.
- AC3: Capture output while a different job remains unfinished; assert immediate baseline-format lines for pass, skip, fail and fallback buckets, failure links, stable ordering, punctuation/spaces, and no repeated event for a pair across snapshots or a later attempt of that pair. Replay cancellation alongside unfinished work, then cancellation alone and cancellation superseded by a successful rerun; assert cancellation is withheld until no checks remain unfinished.
- AC4: Reject remote mutations in the fixtures and compare repository content, index and refs before and after success, failure, timeout and read-error outcomes.
- AC5: Exercise pass/skip-only, failure, cancellation and recovery after an emitted early failure; assert final-state counts, exact closing lines and statuses 0/1. Retain the existing literal fallback-bucket treatment in fixtures.
- AC6: Replay both an empty array and
no checks reported, checks appearing before the bound, and no checks by the bound; assert 5-second appearance spacing, the default and overridden bounds, status 2 and noALL GREENon an empty result. - AC7: Replay unfinished work through the default and overridden settling budgets; assert configured spacing, no premature exit after an early failure,
TIMEOUT, status 2, and independence from the appearance budget. - AC8: Transfer the non-array, failed-read, authentication and partial-processing cases at
tests/skills/watch-pr/scripts/watch-checks.bats:55,tests/skills/watch-pr/scripts/watch-checks.bats:64,tests/skills/watch-pr/scripts/watch-checks.bats:116andtests/skills/watch-pr/scripts/watch-checks.bats:126; assert no partial response can yield green. Include nonzero reads with stdout to preserve the current refusal boundary. - AC9: Transfer
tests/skills/watch-pr/scripts/watch-checks.bats:106; assert one failed request, status 76, primary/secondary guidance, unchanged original stderr, no retry and no budget lookup. Ordinary authentication errors receive no quota guidance. - AC10: Transfer the exact four-read sequence at
tests/skills/watch-pr/scripts/watch-checks.bats:41; count one check read for every snapshot, including appearance and settling phases. - AC11: Run targeted Go tests on Linux, macOS and Windows, race tests for the watcher, then
mise run check,mise run cover-go-checkandmise run cover-py-check, recording results on the reviewed head. Runmise run generate-skills,mise run skill-tokens,apm installandmise run check-generated-skillsonly when this change touches skill sources. Wrapper selection, forwarding and deployed entry-point assertions belong to feat(checks): route the watch wrapper to the Go command #977. - D1–D10: Verify every AC on the merged head and cite its evidence in the PR; obtain independent exact-head approval and passing required checks; complete gitleaks, the repository leak scan and the review of every content post; sign commits and squash; update docs; include Assisted-by trailers and the provenance:agent-assisted label; check actual PR size limits; file follow-ups with Problem and numbered ACs, list them in PR Related and link deferred code to them; close the issue with a closing reference, move it to Done and record the merge commit in the final Status comment.
Risks
The saved-rollup evaluator and watcher disagree about ordering and status semantics. Reusing its verdict without preserving the watcher contract would change results. The existing watcher treats nonzero check reads as errors even when stdout is present, and #375 tracks that. Display ambiguity stays with #310.
Undo: revert this change. Nothing calls the new command until the wrapper child merges.
Operator authority
None
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsDone
Activity
tbhb-dev-reviews commentedon Oct 31, 2026
Refinement: NOT READY — make command verification independent of the wrapper child
Checked
Read #976, parent Epic #793, sibling #977, and PRs #961 and #962 using the read-only agent GitHub configuration. Accepted the supplied mechanical-gate pass; did not rerun it. No tests or suites were run.
AC1–AC11 match the parent's AC1–AC11, with observable outcomes and a Verify-plan entry for each ID. #977 AC1 maps exclusively to parent AC12, so the children cover the parent's criteria without overlap. The pinned shell contract makes the parity assertions testable. Read-only operation, request cost, platform parity, quota handling and bounded waits are explicit. Risks and revert are stated; Operator authority None fits this command. The dependency direction is correct: #977 follows #976; #242 is already merged, and #321 identifies the shared-access work. M is a plausible command-only planning size, subject to the actual PR size gate.
Gaps
internal/agentrepo/watch_command_internal_test.go:1and shell parity coverage intests/skills/watch-pr/scripts/watch-checks.bats:1. Specify that all evidence needed to close feat(checks): add the Go pull request watch command #976, including AC4 and command parity, lands with feat(checks): watch pull requests in Go #961; move or add the necessary command tests there. feat(checks): route the watcher through Go with fallback #962 should consume the verified command and prove parent AC12. Otherwise the prerequisite can merge without demonstrating its own ACs, and completion depends on its dependent child.The existing shell can serve as the command child's parity oracle without becoming a wrapper: target/prerequisite behavior is at
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:53, snapshot acquisition atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:82, and final judgement atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:177.Split
Keep the existing two-child split: #976 owns parent AC1–AC11; #977 owns parent AC12 and depends on #976. No additional child is needed. Separate verification ownership as well as implementation ownership, and update the PR descriptions to reference their new child issues.
Definition of done
Ticks assess coverage in the ACs and Verify plan, not completed implementation or permission to merge.
The devtools-specific check/coverage floors and generation sequence are present; assign generation/deployment assertions to the child that changes those sources.
Round: 1 of 3
tbhb-dev-reviews commentedon Oct 31, 2026
Refinement: READY — command verification now belongs entirely to the command child
Checked
Read revised #976, its round 1 Refinement comment, parent Epic #793, sibling #977, and PRs #961 and #962 using the read-only agent GitHub configuration. Accepted the supplied mechanical-gate pass without rerunning it. No tests or suites were run.
Round 1 gap 1 is closed. The failing-test step now exercises Go directly, with the pinned existing shell as its parity oracle. AC11 reserves wrapper selection, forwarding and deployed-entry-point assertions for #977; generation is conditional on touching skill sources.
Round 1 gap 2 is closed at the refinement level. Approach explicitly requires all evidence closing #976, including AC4 state preservation and command-versus-shell parity, to land in #961 without depending on #977. AC4 checks content, index, refs and remote mutations across success, failure, timeout and read errors. Implementation and PR-description alignment remain delivery obligations; this verdict does not certify those PRs.
AC1–AC11 preserve parent AC1–AC11 verbatim and express observable outcomes. Every ID has a substantive Verify-plan check. Sibling #977 AC1 covers parent AC12 exclusively, so ownership covers the parent without overlap. Read-only operation, request counts, platform parity, quota handling and bounded waits are explicit. The pinned contract supports discovery at
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:53, attempt selection atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:98, cancellation atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:134, and final recount atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:177.M is a plausible single-PR command slice, subject to actual size gates. Risks distinguish watcher and saved-rollup semantics; reverting the unused command provides an undo. Operator authority None fits this work. No gate loosening is proposed. #242 is merged; #321 identifies shared-access work. The declared dependency direction is correct: #977 follows #976.
Gaps
No remaining blocker in #976's readiness plan.
Delivery follow-through: #961 still says AC4 is unchecked and references #824; #962 still describes command-state and parity evidence as its own. Move or add that evidence to #961 and align both descriptions with #976/#977 before claiming completion. The revised issue now explicitly requires this work rather than relying on its dependent child.
Dependency metadata follow-through: native dependency reads currently show no link between #977 and #976, despite #977's prose claiming one. Record #977 blocked by #976 before treating the wrapper as ready to start. This downstream metadata correction does not prevent starting the command child.
Split
Keep the existing split: #976 owns parent AC1–AC11 and its complete verification; #977 owns parent AC12 and depends on #976. No further split is needed.
Definition of done
Ticks assess coverage in the ACs and Verify plan, not completed implementation or permission to merge.
The plan includes devtools' check and separate coverage floors, targeted platform/race verification, and the conditional generation, token and deployment sequence. Wrapper deployment verification stays with #977.
Round: 2 of 3
tbhb-dev-reviews commentedon Oct 31, 2026
Refinement: NOT READY — the epic still closes before the new parity child
Checked
Read amended #976, its previous READY Refinement comment, parent #793, siblings #977/#978, and PRs #961/#962 (bodies, file lists and relevant patches) with the read-only agent GitHub configuration. Accepted the supplied mechanical PASS without rerunning it. No tests, builds, suites or live watch ran.
#976 AC1–AC11 remain verbatim parent AC1–AC11, with unchanged IDs and substantive Verify-plan checks for every ID. They describe observable behavior. Read-only state preservation, one read per snapshot, platform parity, quota refusal and bounded waits remain covered. The baseline supports discovery at
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:53, attempt selection atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:98, and final recount atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:177.The revised allocation is coherent: #976 retains direct command regressions and AC4 evidence in #961; #977 owns parent AC12 as child AC1, including the offline capability-probe test; #978 owns comparison of both implementations on identical scripted responses. These are separate verification responsibilities, not duplicate acceptance ownership. #962's proposed TestWatchProbeOffline invokes help outside a repository with an empty PATH and checks usage output, status 0 and empty stderr. Wrapper compatibility follows
docs/compatibility.md:3.Native GraphQL relationships confirm all three children have parent #793, with #977 and #978 blocked by #976. #976 has no native blocker. M remains a plausible single-PR command slice, subject to actual size gates. Its risks, revert and Operator authority None fit this work; no protected-policy or gate change is proposed (
.agents/agent-skills.conf:4).Gaps
Delivery follow-through, not another readiness blocker: #961 still reports AC4 unchecked and refers to #824; #962 still claims command-state and parity evidence. Align descriptions and test placement with revised ownership before claiming completion. Retain the Bats parity case until #978's replacement lands, as #978 requires. A discovered behavior difference can block wrapper delivery even though #978 is not currently a formal prerequisite of #977.
Split
Keep #976 M for parent AC1–AC11, #977 S for parent AC12, and #978 S for the offline parity proof. No further split is needed. Correct the epic's verification and completion accounting; parity need not move back into #976.
Definition of done
Ticks assess planning coverage in this child's ACs and Verify plan, not completed implementation or merge evidence.
Round: 1 of 3
tbhb-dev-reviews commentedon Oct 31, 2026
Refinement: READY — the epic now requires all three children and the parity proof
Checked
Read #976, its previous READY Refinement comment and the scope-change round 1 finding, parent #793, siblings #977/#978, and PRs #961/#962 using the read-only agent GitHub configuration. Inspected relevant #962 test patches and the pinned shell baseline. Accepted the supplied mechanical-gate PASS without rerunning it. No tests, builds, suites or live watching were run.
The scope-change round 1 gap is closed. #793 now names all three children in its outcome, verification, child list and completion condition, and explicitly requires #978's cross-implementation evidence before closure. #976 now names #978 in its problem, exclusions, approach and dependencies; #977 explicitly assigns parity to #978. The parent retains AC1–AC12, #976 retains AC1–AC11, and #977 retains AC1 mapped to parent AC12. No existing AC ID changed.
Ownership is complete: #976 proves parent AC1–AC11 directly against Go; #977 proves parent AC12, including the offline capability probe; #978 compares command and baseline shell stdout, stderr, status and read counts on identical scripted responses. The comparison is an additional epic closing condition, not duplicate behavioral AC ownership. Overlapping scenarios supply different evidence. #978's baseline fixture is independent of the wrapper's fallback location, so it need not wait for #977.
All eleven command ACs describe observable outcomes and have substantive Verify-plan checks. Read-only operation, request count, platform parity, bounded waits and quota refusal are explicit. Target selection and refusal evidence starts at
packages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:53; attempt ordering is atpackages/agents/source/skills/watch-pr/shared/scripts/watch-checks.sh:98. Wrapper compatibility matchesdocs/compatibility.md:3. #977 expressly owns TestWatchCommandProbe/TestWatchProbeOffline and verifies no probe reads or side effects; the proposed offline test invokes help outside a repository with an empty PATH.Native dependency reads confirm #977 and #978 are blocked by #976. Shared-access/evaluator context remains #321/#242; fallback retirement stays with #333/#544. M is a plausible command-only single-PR size, subject to actual size gates. Risks distinguish watcher and saved-rollup semantics; reverting the unused command supplies an undo. Operator authority None fits the scope. All command-closing evidence explicitly belongs in #961, independently of #977/#978.
Gaps
No remaining readiness blocker.
Delivery follow-through: #961 still references #824 and reports AC4 unchecked; #962 still claims command-state and parity coverage. Move or add all command-closing evidence, including AC4, to #961 and align both PR descriptions with #976/#977/#978 before claiming completion. Retain the existing Bats parity case until #978's replacement lands, then remove it as #978 specifies. A real difference found by #978 can block wrapper delivery, as the epic now acknowledges. These obligations are captured by the revised issues and do not leave an AC uncovered.
Split
Keep #976 M for parent AC1–AC11, #977 S for parent AC12 and the offline probe, and #978 S for cross-implementation proof. No further split is needed. Both downstream children depend on #976; epic closure requires all three merged with recorded evidence.
Definition of done
Ticks assess coverage in the ACs and Verify plan, not completed implementation or permission to merge.
The plan also includes targeted platform/race verification, mise run check and the separate Go/Python coverage floors. Generation, tokens, installation and generated-output checks are conditional on skill-source changes; wrapper deployment and consumer migration evidence remain with #977.
Round: 2 of 3
feat(checks): watch pull requests in Go
feat(checks): watch pull requests in Go
feat(checks): watch pull requests in Go
tbhb-agent commentedon Oct 31, 2026
Proof allocation: #961 covers AC1 except its nested-directory and missing-repository cases, AC2, AC3, AC5 through AC10 and the settings and environment half of AC11. #994 covers AC4, those two AC1 cases and the portable-fixture half of AC11. #976 closes when #994 merges.
feat(checks): watch pull requests in Go (#961)
test(checks): prove the watch command leaves the repository untouched