Skip to content

fix(api): one file to send when asking for help, with the slot's energy books in it - #753

Merged
frahlg merged 3 commits into
masterfrom
fix/support-dump-zip
Aug 3, 2026
Merged

fix(api): one file to send when asking for help, with the slot's energy books in it#753
frahlg merged 3 commits into
masterfrom
fix/support-dump-zip

Conversation

@frahlg

@frahlg frahlg commented Aug 3, 2026

Copy link
Copy Markdown
Member

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/report still 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:

  • the plan never reached dispatch, or
  • dispatch already finished the slot's energy and is coasting

Both look identical from outside. So control.State now exposes SlotEnergy():

PlannedWh what the plan asked for this slot
ActualWh what the fleet actually moved — every tick, every path
EnergyPathWh 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.

On Björn's numbers it reads:

PROBLEM — The slot's energy is not being delivered. This slot asked for 1.12 kWh and the batteries have moved 20 Wh with 8 min of it gone — about 3% of the rate the plan needs. The energy-allocation path has delivered nothing this slot, so a reactive path is driving instead of the plan. Safety limits, a charge ceiling and a device that cannot follow the command all look like this from here — the dispatch table and the log below separate them.

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 verify clean, 272 web tests green.

🤖 Generated with Claude Code

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>
@frahlg
frahlg requested a review from erikarenhill as a code owner August 3, 2026 08:56

@miravoss26 miravoss26 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:359 the manifest comment still reads tar -xOzf ... manifest.json, which is stale now that it's a zip. unzip -p ... manifest.json is 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>
@frahlg frahlg changed the title fix(api): ship the support dump as a zip fix(api): one file to send when asking for help Aug 3, 2026
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>
@frahlg frahlg changed the title fix(api): one file to send when asking for help fix(api): one file to send when asking for help, with the slot's energy books in it Aug 3, 2026
@frahlg
frahlg merged commit 8b59603 into master Aug 3, 2026
13 checks passed
@frahlg
frahlg deleted the fix/support-dump-zip branch August 3, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants