docs(debug-journal): recover the stalled backlog and correct five entries - #4980
Merged
Conversation
…ries The first flush since the journal became writable again. Four candidates that the 2026-09-06 and 2026-09-07 runs verified but could not land, plus the corrections those runs found while re-reading the file against what has merged since. Folded in: - GH#4967 - the `octopus_intelligent_consider_full` clamp is duplicated in prediction_kernel.cpp, `car_charging_limit` is held by reference, and the clamp is currently the only bound on GH#4952's overestimate. Extends the car-charging row. - GH#4975 - new symptom row for "low power mode does nothing": the PV-overlap guard is a fixed 0.1 kWh threshold and midday windows are expected to fail it, so these are enhancement reports rather than defects. - GH#4965 - new trap. The interesting half is that the harness cannot reproduce the crash the issue describes, so a guard-presence assertion is the only honest regression test. Rewritten rather than folded: - GH#4973 claimed `gh search issues` was dead on the runner. Re-probing dissolved the premise - the run had silently corrected a typo in the issue title it searched for. The salvageable lesson went into the existing duplicate-search bullet. Corrected: - Octopus row: GH#4946 fixed by PR #4957 (`dispatch_billed_off_peak()`) - Fox row: the half of GH#4939 the reporter actually hit was event routing, fixed by PR #4962; the zero-caller `set_battery_charging_time()` half is still live - Carbon row: half (a) fixed by PR #4958; half (b) narrowed to what is still true - GivTCP row: PR #4864 moved REST handling out, so the `inverter.py:1435` citation had drifted onto unrelated code - Two-scans trap: both halves fixed by PR #4943, was written in present tense Every claim above was re-verified against main at f0cb3f0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
springfall2008
force-pushed
the
bot/debug-journal-2026-09-07
branch
from
September 7, 2026 07:21
6e3c3cf to
3423c71
Compare
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
journal_pr_opened() can crash the daemon on invalid/non-JSON gh output because json.loads() isn’t guarded, undermining the intended “fail closed and preserve the queue” behavior.
Pull request overview
This PR recovers and corrects the triage debug-journal backlog, and hardens the /journal-update flush so verified findings aren’t silently lost when the run can’t actually write/open its PR. It also updates internal agent/skill docs to reference the new journal location.
Changes:
- Move the debug journal reference to
tools/debug-journal.mdand update the daemon + skill/docs pointers accordingly. - Gate queue archiving on a PR existing for today’s journal branch (protects against “blocked but exit 0” flushes).
- Fold in multiple debug-journal corrections/additions (Octopus, Fox, Carbon, GivTCP, low-power charging symptom row, etc.) and add tests covering the new flush semantics.
File summaries
| File | Description |
|---|---|
| tools/triage_daemon.py | Moves journal path and changes flush semantics to archive only after a PR exists (adds journal_pr_opened() and passes today). |
| tools/test_triage_daemon.py | Updates/extends tests for new journal path constraint and “archive only if PR exists” behavior. |
| tools/debug-journal.md | Recovers backlog and corrects multiple entries; adds new symptom/trap notes and marks fixed items as fixed while keeping mechanism. |
| CLAUDE.md | Updates debug-journal path reference. |
| AGENTS.md | Updates debug-journal path reference. |
| .claude/skills/journal-update/SKILL.md | Updates maintained journal path and git add instructions for the new location. |
| .claude/skills/issue-triage/SKILL.md | Updates links to the debug journal. |
| .claude/skills/issue-triage-followup/SKILL.md | Updates links to the debug journal. |
| .claude/skills/issue-pr/SKILL.md | Updates links to the debug journal. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A sweep of the triage bot's logs for findings that never reached the queue. - Ohme row, GH#4952 (still live): `slot_list()` derives energy as `watts * hours` while the observed amperage taper shows `watts` is a per-slot cap - 2.55x over on the reporter's data - and the `estimatedSoc` field that would give the true delta is never read. The same slots publish as AT_HOME dispatches with no source, so the whole block is stamped at the low rate. Cross-referenced to the car-charging row's fix-order note, since the predict() clamp is currently the only bound on it. - Octopus row, GH#4950 (fixed, PR #4951): the low-rate slot budget was keyed on the loop minute rather than the slot start, so a noon-straddling window drew a fresh budget at midday. Had no entry at all. - New trap: `midnight_utc` is local midnight and `now_utc` is local time. Both names are wrong in the same direction, and it already sent one review hunting for a timezone frame mismatch that does not exist. Deliberately not folded in: PR #4957's "three unshared copies of the dispatch predicate" finding, which the merge it reviewed has since addressed - `dispatch_billed_off_peak()` is now a shared helper and the one remaining plain location test carries an explicit #4946 cross-reference. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Recovers the debug-journal backlog that the flush could not land. Rebased onto
mainnow that #4979 has merged, so the diff is a single file:tools/debug-journal.md.This is the work the 2026-09-06 18:20 and 2026-09-07 00:00 runs did and then discarded: both verified their candidates in full, hit the
.claude/write block, explained themselves and exited 0. Every claim below has been re-verified against main atf0cb3f0d, not carried over on trust.Folded in
GH#4967 — the
consider_fullclamp has a twin in the C++ kernel. Extends the car-charging row with the three things the issue does not mention: the clamp is duplicated verbatim atprediction.py:799andprediction_kernel.cpp:827(fix one and the plans diverge),octopus_intelligent_consider_fullnever reachespredict()at all, andcar_charging_limitis held by reference and read byexecute.pyfor a real control decision — so a fix must assign a separate model-facing value, not mutate it. Also records the fix-order dependency: that clamp is currently the only thing bounding GH#4952's overestimate.GH#4975 — new symptom row for "low power mode does nothing". The PV-overlap guard in
find_charge_rate()uses a fixed 0.1 kWh threshold (const.py:83), not one scaled to system size, and the GH#4577 dawn split only protects the pre-dawn part of a window — so a window lying entirely in daylight can never engage low power. That is by design (PR #4373), which makes this class of report an enhancement rather than a defect. Worth having as a row because it is a repeat: GH#3311, #4557, #4699, #4975.GH#4965 — new trap, and the second half is the useful one. The
test_control_ledger.pystub trap is minor. The finding worth keeping is that the harness cannot reproduce the crash the issue describes: the clock-skew read sits behindif "discharge_start_time" in self.base.args:, which the mock inverter never satisfies, so an attribute-deletion reproduction passes whether or not the bug is fixed. Verified by stashing the fix and re-running the suite. Assert the guard is present instead.(Note: the candidate located this behind
if self.discharge_enable_time:. That gate closes two lines earlier; the real one is theargscheck. The observation held, the explanation did not — corrected before folding.)Rewritten rather than folded
GH#4973 claimed
gh search issueswas silently dead on the runner. Re-probing dissolved the premise: the search worked, and the "must-hit" query missed because the run had silently corrected a typo in the issue title while retyping it. Folding the original claim would have told future runs to distrust a working tool. The salvageable half — treat an empty duplicate-search result with the same suspicion as a confident one — went into the existing bullet.Existing entries corrected
dispatch_billed_off_peak()prices completed dispatches off-peak regardless of locationpredbatprefix. The zero-callerset_battery_charging_time()half is still livecarbon_replicate()only reduces how many minutes reach itinverter.py:1435citation had drifted onto unrelated code after REST handling moved togivtcp_rest.pyFixed entries keep their mechanism rather than being deleted — a reader holding an older log still needs it.
Nothing dropped
All four candidates produced something. Also checked and found already current: the GE Cloud row (corrected in #4969), Sigenergy #4926, Solis #4875/#4923, the memory row, and the still-unmerged Solis guards.
Second commit: a sweep of the run logs
The user asked for the bot's logs to be reviewed for anything that never reached the queue. Three more findings, all verified against main:
slot_list()derives energy aswatts * hours(ohme.py:124) while the observed 16A→10A→6A taper showswattsis a per-slot cap — 2.55x over on the reporter's data. Ohme publishesestimatedSoc, which would give the true delta, andohme.pynever reads it. The same slots publish asAT_HOMEdispatches with nosource(ohme.py:670), so the whole plug-in-to-target block is stamped at the low rate. Cross-referenced to the car-charging row, because thepredict()clamp is currently the only thing bounding it.midnight_utcis local midnight, andnow_utcis local time. Both names are wrong in the same direction —update_time()setsnow_utc_real = datetime.now(self.local_tz)(predbat.py:654). This already sent one PR review hunting for a timezone frame mismatch that does not exist.Deliberately not folded in: PR #4957's review flagged "three unshared copies of the dispatch predicate". The merge it reviewed has since addressed that —
dispatch_billed_off_peak()is a shared helper and the one remaining plain location test carries an explicit #4946 cross-reference. Folding it would have added a stale warning to the file.Note on spelling
The GH#4973 entry needs to talk about a typo in an issue title. I reworded around it rather than adding a misspelling to
.cspell/custom-dictionary-workspace.txt— the dictionary is for real vendor terms.run_pre_commit: clean.🤖 Generated with Claude Code