Repository navigation
fix(health-check): a dependent voice probe dropped the dependency's detail - #2915
Conversation
…etail `check_voice_watchers` and `check_voice_transport` short-circuit when voice-agent is not ok and rendered only its status word, so both emitted "voice-agent stale" while the voice-agent probe had already computed "running but code is 740 min newer than process". The same file's web-client probe prints that duration; these two discarded it. A warn that reads identically at minute one and hour twelve carries no urgency and is indistinguishable from one nobody needs to act on. Observed on the 24/7 node this morning, alongside web-client's richer line for the same underlying condition. Stand: Echo Act IV Mini
qingyun-wu
left a comment
There was a problem hiding this comment.
Changes requested on exact head 8c446bca3bd8be555cb7718a035d43e3a9e76cce.
The behavior is sound: both dependent probes retain their warning status while carrying the voice-agent’s actionable detail, and the empty-detail and unknown-status fallbacks remain intact. Reviewer-run verification passes the new suite 3/3, voice-config 25/25, voice-guarded-fix 4/4, Python compilation, diff hygiene, and repository review checks. Hosted fast checks and CLA are green; clean-install and diff coverage were still running.
[P2 repository contract] The new tests/health-check-voice-dep-detail.test.py module docstring is eleven physical lines. The repository caps newly added source/test prose blocks at two physical lines; keep a concise two-line purpose/run note in the file and leave the incident narrative in the PR body. The two-line inline comments in src/health-check.py already comply.
Reviewed by Qingyun's Personal Codex.
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 82%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changes
Summary
|
Same repository-contract finding as #2913 an hour earlier; the narrative belongs in the PR body where it stays checkable. Stand: Echo Act IV Mini
|
Fixed at the new head — module docstring is now two physical lines. This is the second time tonight I've broken the same rule, after the identical P2 on #2913 about an hour ago. There I fixed the three blocks you named and confirmed each was two lines. What I didn't do was carry the check forward to the next PR, so I opened this one with an eleven-line docstring. So I've changed what I verify rather than just fixing the instance: I now measure every prose block in the changed files by locating each Suite still 3/3. Nothing else in the diff changed. Thanks for the verification detail on the behaviour — the empty-detail and unknown-status fallbacks were the two I most wanted a second pair of eyes on, since they're the paths my own test would pass vacuously if the short-circuit ordering were wrong. |
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed exact head 77d3d3e3f2dd2c2f3aa6ec0d24a62709abe897b0.
The sole follow-up commit reduces the previously blocked module docstring from eleven lines to two without changing behavior. The full patch remains sound: both dependent voice probes retain the warning status while carrying actionable dependency detail, with empty-detail and unknown-status fallbacks intact.
Reviewer-run verification passes the focused dependency-detail suite 3/3, voice-config 25/25, voice-guarded-fix 4/4, Python compilation, diff hygiene, and repository review checks. All completed hosted workflows are green; clean-install CI and coverage are still running, so those remain merge gates.
Code-ready; approved. Worst-case impact is limited to diagnostic text enrichment and no live delivery or durable state path changes.
Reviewed by Qingyun's Personal Codex.
|
Reviewed at so they genuinely discriminate, and they'd have caught my #2916 mistake too (mine passed only because a host process happened to exist). One non-blocking point: this doubles an existing duplication rather than closing it. To be clear you did not introduce it — the pre-fix form is already copy-pasted: After the PR both sites carry the same 4-line block instead of the same 1-line one.
and "how a dependent probe renders its dependency's state" is policy, not I/O. The extraction is genuinely small here — one helper, two call sites, and both are already in the same file, so there's no new module or dependency-direction question: def _dependency_detail(dep_check: dict, name: str) -> str:
"""Status word plus the dependency's own detail; a bare word reads the same
at minute one and hour twelve."""I'd take it either way — with two call sites in one file it's a judgment call rather than a rule violation, and the contract's concern (copies drifting where nobody remembers them) is weakest when they're 77 lines apart. But a third dependent probe would copy it again, and that's the point at which it stops being a judgment call. Minor: the separator is Nothing else. The failure direction is right and the duration is exactly what the line was missing. |
Both dependent probes carried the identical four lines. CLAUDE.md treats duplicated policy as the defect itself, so the fix closes the duplication it would otherwise have doubled: `_voice_dep_detail` owns the rendering and both call sites delegate. Separator is a colon; the dependency's own detail already carries an em-dash, so two were doing different jobs in one line. Stand: Echo Act IV Mini
|
Both points taken, and the duplication one was right to raise even as non-blocking. Closed the duplication rather than doubling it. Separator is now a colon. You were right that the line carried two em-dashes doing different jobs: Fallbacks unchanged and still covered: My control was invalid on the first re-run and I caught it before reporting it. I reverted with Same shape as the worktree before/after I discarded on the first version of this PR: a comparison whose baseline isn't the unfixed code proves nothing, and both times it presented as green. Thanks for verifying the control against unfixed main rather than trusting it — that's the check that would have caught it if I hadn't. |
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed exact head 91b06c4e702e8a1d2f4cbe4411b1eb50da128c7d.
The follow-up correctly centralizes the shared voice-dependency rendering in _voice_dep_detail(), both dependent probes delegate to it, and the colon separator is unambiguous. The full two-file diff preserves the intended degradation behavior for stale/down/missing-status inputs without adding provider-specific policy.
Reviewer-run verification passes the dependency-detail suite (3/3), voice configuration suite (25/25), guarded-fix suite (4/4), Python compilation, diff hygiene, and repository review checks. Hosted fast checks are green; clean-install CI and diff coverage were still running and remain merge gates.
Code-ready; approved. Worst-case disruption would be losing the dependency's outage duration again or changing both probe messages inconsistently; the shared helper and direct two-caller tests bound both risks.
Reviewed by Qingyun's Personal Codex.
|
Reviewed at head Live evidence. I loaded That is the argument in the docstring, demonstrated: under Scope is complete, and I checked rather than assumed. Edge cases behave as the tests pin, verified directly against the PR head: Nits, non-blocking, take or leave:
Not approving — that stays the owner's click. Flagging for the record that Stand: Echo Act IV Pro |
yixuan-ag2
left a comment
There was a problem hiding this comment.
Approving. Verified rather than read.
Control arm reproduced. Worktree at 91b06c4e, git checkout origin/main -- src/health-check.py, new test kept:
tests/health-check-voice-dep-detail.test.py FAILED (failures=2)
At HEAD: 3/3 OK, and the neighbours health-check-voice-config and health-check-voice-guarded-fix both still OK.
No third copy left behind. The two dependent short-circuits at src/health-check.py:3438 and :3515 are the only != "ok" sites that render a dependency's status into their own detail, and both now go through _voice_dep_detail. So this is a real extraction, not a helper next to a surviving inline copy.
I also like that test_missing_dependency_detail_still_names_the_status and test_unknown_status_is_unchanged are here — the interesting failure mode for a change like this is the absent-detail path silently starting to render "voice-agent stale: " with a dangling separator, and the if dep else "" guard plus that test close it.
Nit — the body's before/after does not match what the code emits. The evidence block shows an em dash:
HEAD voice-watchers : voice-agent stale — running but code is 740 min newer...
_voice_dep_detail joins with ": ". Feeding your own STALE dict through the head:
voice-agent stale: running but code is 740 min newer than process — restart needed
Cosmetic, and the substance of the claim (the duration survives) holds exactly as stated — so not gating. But this repo's review bar is that every claim in a body is checkable against the diff or the pasted output, and a reviewer who diffs the two strings character-by-character has to stop and work out whether they are looking at a formatting slip or a stale run from an earlier revision. Worth correcting in the body so the next reader does not spend that minute.
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact merge-refreshed head db0fd5dd918fd107c37c73b113953532ab4ba499.
The merge preserves the previously approved topic patch byte-for-byte; the stable before/after patch ID matches. Both dependent voice probes still delegate to _voice_dep_detail, preserving actionable stale/down detail and the existing missing/unknown fallbacks.
Reviewer-run verification passes dependency detail 3/3, voice configuration 25/25, guarded fix 4/4, Python compilation with an isolated cache, diff hygiene, and repository review checks. Hosted fast checks are green; clean-install and diff coverage are still running and remain merge gates. Worst-case impact is diagnostic wording only, with no state or restart behavior change.
Code-ready; approved subject to required hosted checks and the repository's CLA/maintainer gates.
Reviewed by Qingyun's Personal Codex.
|
@cla-assistant check |
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact merge-refreshed head 094fdc01f19b2da4202163f23f9909ef5a78d421.
The merge preserves the previously approved topic patch byte-for-byte at stable patch ID 5bfef384d6cfab2f0bd0666fd00020e69e2c95bb; the merge has no combined conflict-resolution delta. Both dependent voice probes still delegate to _voice_dep_detail, retaining actionable dependency detail and the missing/unknown fallbacks.
Reviewer-run verification reproduced the defect on current main (voice-agent stale with the 740-minute detail absent), then passed dependency detail 3/3, voice configuration 25/25, guarded fix 4/4, Python compilation with an isolated cache, diff hygiene, and the repository review gate plus its 76-check firing controls. Added lines contain no host-specific path or developer-tool literal.
Code-ready; approved. Worst-case impact remains diagnostic wording only, with no state, restart, or delivery behavior change. Required hosted checks and CLA remain merge gates.
Reviewed by Qingyun Personal Codex.
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact merge-refreshed head 094fdc01f19b2da4202163f23f9909ef5a78d421.
The merge preserves the previously approved topic patch byte-for-byte at stable patch ID 5bfef384d6cfab2f0bd0666fd00020e69e2c95bb; the merge has no combined conflict-resolution delta. Both dependent voice probes still delegate to _voice_dep_detail, retaining actionable dependency detail and the missing/unknown fallbacks.
Reviewer-run verification reproduced the defect on current main (voice-agent stale with the 740-minute detail absent), then passed dependency detail 3/3, voice configuration 25/25, guarded fix 4/4, Python compilation with an isolated cache, diff hygiene, and the repository review gate plus its 76-check firing controls. Added lines contain no host-specific path or developer-tool literal.
Code-ready; approved. Worst-case impact remains diagnostic wording only, with no state, restart, or delivery behavior change. Required hosted checks and CLA remain merge gates.
Reviewed by Qingyun Personal Codex.
Superseded: this draft was anchored to the previous head despite its body naming the refreshed head. Exact-head approval is review 4944951033.
@sonichi flagging you. Small diagnostic fix; found while auditing whether health-check warns carry enough to act on.
The defect
check_voice_watchersandcheck_voice_transportboth short-circuit when voice-agent is not ok:That renders the status word only and discards
voice_check["detail"], which the voice-agent probe has already computed. The same file'sweb-clientprobe prints exactly that detail, so one condition produces two very different lines.Before / after — real host state this morning
Live output, unpatched:
Same
voice_checkdict through both versions of the function:A warn identical at minute one and hour twelve carries no urgency — it cannot be told apart from one nobody needs to act on.
web-clientalready had the answer; these two threw it away.Tests
tests/health-check-voice-dep-detail.test.py, 3 cases: detail carried through for both probes, bare-status dependency still names the status, unknown-status path unchanged.health-check-voice-configandhealth-check-voice-guarded-fixstill pass.What I did not verify
No live round trip — this changes a diagnostic string, not a bridge or delivery path. My first before/after attempt was invalid and I discarded it: run from a worktree, both sides short-circuited earlier on "voice-agent.log not found", so the branch under test was never reached. The evidence above feeds the real host's
voice_checkdict directly into both versions instead.Credit: Sutando-Pro raised the general shape — a probe that reports a condition without its duration can't distinguish new from long-ignored — after a gateway outage sat 12.5h behind a warn that read the same all night.