Skip to content

feat(stats): send the daily energy report straight to FTW Cloud until a relay exists - #2007

Open
frahlg wants to merge 1 commit into
masterfrom
energy-report-direct
Open

frahlg wants to merge 1 commit into
masterfrom
energy-report-direct

Conversation

@frahlg

@frahlg frahlg commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Problem

stats.ftw.energy shows no energy. The daily energy report (go/internal/energyreport) may only leave through an independent OHTTP relay, and statsrelay.RelayURL and GatewayKey are empty. So no box has ever sent one. The fleet report had the same problem until #1989 (8 November): every box that shares now sends it straight to /v1/fleet.

Fredrik decided on 12 November 2026 that the energy report does the same.

Change

  • statsrelay.Default() is the pinned relay when this build has one, and otherwise a direct client for statsrelay.DirectURL (https://cloud.ftw.energy/v1/energy, a compile-time var like RelayURL).
  • The direct client posts the same padded inner request (reportwire.Request, 1,536 bytes) unsealed, as message/bhttp, and believes only a 204. Same random id per report, same UTC send day, no retry, no redirect.
  • energyreport uses Default(). Nothing else about it changes: the same one statistics answer, the same partner rule, the same 1–12 hour window after the day closes, a day with a gap still skipped.
  • The settings preview gains endpoint; relay stays the relay only. Settings → FTW app → Anonymous statistics says the report goes straight to FTW Cloud, that Cloud sees the address while the request is open, and that it keeps neither the address nor the report.
  • ADR 0008 gets a dated amendment (8 and 12 November) that states the cost plainly: until a relay exists, Sourceful alone could match an energy report to a fleet report by address and time; the service does not, but that is a rule in code. docs/architecture.md and docs/protocol-cloud.md say the same in a line.

Once a release pins a relay, both reports go through it, as before.

Pair

  • srcfl/ftw-cloud#61 adds POST /v1/energy. Merge and deploy it before a beta carries this. Before that deploy the box gets a 404 and loses that day; nothing else breaks.
  • srcfl/ftw-webapp#124: the stats page.
  • docs(privacy): describe the daily energy report ftw-web#43: the privacy page describes the energy report.

Changeset

minor: boxes start sending a report they did not send before, which owners see in Settings. Fredrik approves a minor in the PR.

Evidence

go test ./internal/statsrelay/... ./internal/energyreport/ ./internal/api/ ./cmd/ftw/   # ok
node --test web/fleet-ping-tab.test.mjs   # 31 pass

New tests: TestWithoutARelayAReportGoesStraightToFTWCloud (default goes to /v1/energy with no relay pinned; body padded to 1,536 bytes; message/bhttp; a 400, a plain 200 and a redirect all count as failed), TestWithoutARelayTheReportGoesStraightToFTWCloud (box to fake Cloud, the day is remembered) and the settings line tests.

make verify passes locally. The first run hit a port clash in go/internal/ocpp (TestUnsupportedBootTriggerLeavesIdentityUnknown, "address already in use"), a package this PR does not touch; it passed three times alone and the second full run was green.

The Settings line was checked in a browser: the real web/settings/tabs/fleet.js rendered with a stubbed /api/fleet-ping, showing "Sent straight to FTW Cloud at https://cloud.ftw.energy/v1/energy, once a day, 1 to 12 hours after the UTC day ends."

🤖 Generated with Claude Code

… a relay exists

The energy report waited for an independent relay that does not exist, so no
box sent one and stats.ftw.energy showed no energy. A build without a relay
now posts it to https://cloud.ftw.energy/v1/energy, as the fleet report goes
to /v1/fleet since 8 November: every box that shares reports (Fredrik,
12 November 2026). The body is the same padded inner request the gateway
would open, unsealed. FTW Cloud sees the address while the request is open
and keeps neither the address nor the report. Settings says where it goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T09:39:17.322707Z de9073b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: de9073ba0d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +375 to +376
"Until then it goes straight to FTW Cloud, which sees the address while " +
"the request is open and keeps neither the address nor the report. With " +

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Qualify the unlinkability claim for direct delivery

In the default build without a relay, this paragraph still promises that the energy and fleet reports “cannot be matched,” even though both now reach FTW Cloud with the household's source address visible. Separate random send times do not prevent correlation by address, as the new amendment explicitly acknowledges in docs/adr/0008-ftw-cloud.md:442–444. Saying that the address is not retained does not make correlation technically impossible. Qualify the earlier promise and disclose this temporary limitation beside the statistics switch so owners are not given a privacy guarantee that the new delivery path cannot provide.

Useful? React with 👍 / 👎.

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.

1 participant