fix(api): one file to send when asking for help, with the slot's energy books in it - #753
Merged
Conversation
The dump exists to be handed to somebody else. Windows and every chat client open a zip with no extra tooling; a .tar.gz asks the person whose help you need to go find one first. Same contents, same size — manifest, redacted config, driver health, recent logs and an hour of telemetry, about 6 kB on a two-driver install. Deflate per entry rather than gzip over the whole stream, so an entry can also be read without unpacking everything. The test opens the response with archive/zip and reads every entry, so a renamed tarball would fail rather than pass on the extension alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
miravoss26
reviewed
Aug 3, 2026
miravoss26
left a comment
There was a problem hiding this comment.
Clean swap of /api/support/dump from tar.gz to zip: archive/zip replaces archive/tar + compress/gzip in the handler, the client download label follows (ftw-support.zip), and there's a new test that actually opens the response with zip.NewReader and asserts the entries are readable. All lanes green (core Go, web, go test + vet, full stack).
One nit, doc only:
go/internal/api/api_drivers_debug.go:359the manifest comment still readstar -xOzf ... manifest.json, which is stale now that it's a zip.unzip -p ... manifest.jsonis the zip equivalent if you want to keep the hint.
Security screen: nothing. Same contents as before (redacted config, driver health, logs, 1h telemetry), just repackaged; stdlib only, no new deps; no authz or network change. The per-entry CreateHeader error path silently skips a file, which matches the best-effort write pattern already above it, so no regression.
Safe to merge from my read.
There were two downloads and no way for a user to know which one we wanted: the help report from the plan card, the log bundle from a driver's Diagnose modal. They would send one and we would ask for the other, which is the round-trip the report existed to remove. The dump now leads with the report as 00-help-report.md — named to sort first, because it is the only file most recipients need to read — and the plan card's button downloads that archive. Everything else in there is what you reach for when the report does not settle the question. Zip rather than tar.gz for the same reason the report is one file: it is meant to be handed to somebody else, and Windows and every chat client open a zip with no extra tooling. Deflate per entry, so a single file can be read without unpacking the rest. About 10 kB on a two-driver install. GET /api/support/report still returns the bare Markdown for anyone who wants only the text. The test opens the response with archive/zip, asserts the report sorts first and actually contains Findings, and reads every entry — so neither a renamed tarball nor an empty placeholder passes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A report could show a plan asking for 4.5 kW and a live target of 0 W and give no way to tell the two cases apart: the plan never reached dispatch, or dispatch finished the slot's energy early and is coasting. Both look identical from outside, and both keep arriving as support threads. control.State now exposes SlotEnergy(): what the plan asked for this slot, what the fleet has actually moved (counted on every tick and every path), and what the energy-allocation path believes it delivered. The last one only moves while that path executes, so a real plan figure beside a zero there says a reactive path is driving instead of the plan — a distinction the report previously could not make at all. Alongside the numbers, a finding: once a quarter of the slot has passed and delivery is under half the rate the plan needs, say so. Pace rather than plain energy, because a slot is allowed to start slowly and catch up; what is not normal is being a quarter through having moved nothing. The ratio is signed, so a slot moving energy the wrong way is always a shortfall. The finding names the three explanations it cannot separate — a safety limit, a charge ceiling, a device that cannot follow — and points at the dispatch table and the log, which can. Better to say what is undecided than to guess at a cause. Co-Authored-By: Claude Opus 5 <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.
Two things, both from Fredrik testing #740 on live installs.
One file, not two
"men den hämtar inte mer än en md vid DL?"
There were two downloads and no way for a user to know which one we wanted — the help report from the plan card, the log bundle from a driver's Diagnose modal. They send one, we ask for the other. That is exactly the round-trip #740 existed to remove.
The dump now leads with the report as
00-help-report.md, named to sort first because it is the only file most recipients need to read, and the plan card's button downloads that archive. Zip rather than.tar.gz: the file exists to be handed to somebody else, and Windows and every chat client open a zip without a second tool. Around 10 kB on a two-driver install.GET /api/support/reportstill returns the bare Markdown for curl, scripts, or a quick look in a browser.The slot's energy books
A second report arrived while this was open: plan card reading "Charge battery at 4.5 kW · Now, until 15:00", live target 0 W, 4 kW going out to the grid on
passive_arbitrage.The report could not have answered it. It showed the plan and it showed the target, and gave no way to tell two very different cases apart:
Both look identical from outside. So
control.Statenow exposesSlotEnergy():PlannedWhActualWhEnergyPathWhThe last one only moves while that path executes, so a real plan figure beside a zero there says a reactive path is driving instead of the plan — a distinction the report previously could not make at all.
Alongside the numbers, a finding: once a quarter of the slot has passed and delivery is under half the rate the plan needs, say so. Pace rather than plain energy, because a slot is allowed to start slowly and catch up; what is not normal is being a quarter through having moved nothing. The ratio is signed, so a slot moving energy the wrong way is always a shortfall.
On Björn's numbers it reads:
It names the three explanations it cannot separate rather than guessing at one. Saying what is undecided is more useful than a confident wrong cause, and the tables below it are what settle the question.
This does not fix the underlying behaviour — it makes the next report of that shape self-explanatory instead of another screenshot thread.
Verification
The zip test opens the response with
archive/zip, asserts the report sorts first and actually contains## Findings, and reads every entry — neither a renamed tarball nor an empty placeholder passes. Nine pace cases including wrong-direction delivery, idle slots and discharge slots.make verifyclean, 272 web tests green.🤖 Generated with Claude Code