Skip to content

docs: the owner runs updates; native has no update UI - #1373

Merged
frahlg merged 2 commits into
masterfrom
docs/owner-operated-updates
Sep 24, 2026
Merged

frahlg merged 2 commits into
masterfrom
docs/owner-operated-updates

Conversation

@frahlg

@frahlg frahlg commented Sep 24, 2026

Copy link
Copy Markdown
Member

Summary

Direction for native updates, before #1372 is rebuilt against it.

  • FTW's own work is the EMS and the Energy Planner. The owner operates the host (service manager, when to update, backups off the box, logs), by hand or through their own automation or agent. The project documents the steps and does not run the host.
  • ftw update must run unattended. A new release that does not stay up falls back on its own. A release that changes stored data first makes a verified full backup. The same steps are API calls, so they can be wrapped.
  • On native, the web UI shows the running version, the release notice and the command. It has no update, rollback, restore, channel, snapshot or backup controls. The setup wizard offers no update.

Changes

  • VISION.md: the "Running it, updating it" section states the above.
  • ADR 0007, amended:
    • 2: commit only after a short settling period, so a crash just after readiness still falls back
    • 3: ftw rollback and the API instead of the UI; offline launcher rollback when current cannot start; no pre-update rollback point on native
    • 4: restart is an exit, without the UI button
    • 6: the Pi image uses the same native installer and unit, and moves early because the monthly image still installs Docker 2.x
    • 9: code on master that only an installed 1.x–3.x box would run is not part of their migration
    • 10–14 (new): the owner operates the host; the ftw command set; no update UI on native; schema-changing updates; install-time files and one native layout
    • "What is lost", "What is kept" and the rollout evidence follow those changes.
  • docs/roadmap.md: a row "Updates the owner runs" with its evidence.

Nothing here claims shipped behaviour. The ADR stays "rollout pending".

What the review of #1372 found

  • ftw is not on PATH. The CLI in feat(cli): ship ftw as the native operator command #1372 is not built, packaged or installed. The Core binary routes only update, so ftw doctor starts a setup wizard.
  • Schema changes are blocked. nativeupdate.Prepare refuses any change of state schema, so a native box cannot take such a release at all.
  • No automatic fallback after commit. A Core that crashes after it commits has no automatic way back, and the API rollback needs a running Core.
  • Slow restarts look failed. Native status reports "failed" after 5 minutes, while a trial may run for 6 hours.
  • Install-time files never update. The launcher, the unit and anything else outside releases/ are frozen after install.
  • Old Updates flow still in 0.x:
    • web: about 1,400 lines of update-badge.js, plus the setup wizard's "Update now"
    • Core, workflows and scripts: about 11,000 lines that serve only the Docker/sidecar path
  • No usable rollback point. The pre-update rollback point is taken on native, but nothing on native can restore it.

Next, one PR each

  1. feat(cli): ship ftw as the native operator command #1372 rebuilt:
    • the ftw CLI shipped and installed on PATH
    • native version panel only; setup wizard update removed
    • status threshold fixed
    • ftw startup and Core -port dropped
  2. Launcher and slot hardening: offline rollback, settling commit, no accidental launch on an unknown subcommand, disk check, cleanup.
  3. Schema-changing update with automatic full backup and a tested way back; release guard until then.
  4. Remove the old Updates UI and the Docker/sidecar code from master.
  5. Pi image to native.
  6. Docker 2.x/3.x → native migration with a tested return; then retire scripts/ftwctl.py.

Coordination

#1292 (draft) edits a different paragraph of VISION.md and a different roadmap row, so there is no overlap.

Test

Docs only.

  • .github/brand/check-brand-cleanup.sh passes.
  • .github/check-no-planning-docs.sh passes.
  • No changeset: documentation is auto-exempt.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7

FTW's own work is the EMS and the Energy Planner. The owner operates
the host and runs a few documented steps, by hand or through their own
automation or agent. ftw update must run unattended, fall back on its
own and take a verified full backup before a change to stored data.
The same steps are API calls. The native web UI shows the version and
the release notice only.

ADR 0007 gains decisions 10-14 and adjusts 2-4, 6 and 9: settling
period before commit, offline launcher rollback, no rollback point or
UI controls on native, the ftw command set, schema-changing updates,
install-time files and one native layout for installer, Pi image and
migration. The roadmap gets a row with the evidence.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codex Review Summary

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

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-24T06:12:08.334474Z 9168e55 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: 9168e553c4

ℹ️ 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 thread docs/adr/0007-self-updating-binary.md Outdated
Comment on lines +193 to +197
Core first makes and verifies a full backup of the current data, then
installs the release; `--backup-dir` also copies that backup off the
box. The way back across that step is an offline restore of the backup
with the previous release. Until that path exists and is tested, the
native release workflow must refuse a release whose state schema

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve automatic fallback across schema migrations

When the release guard is eventually lifted for a schema-changing update, the trial Core must open and migrate the live state before reaching readiness; if it then crashes during the settling period, decision 2 starts the old current, even though go/internal/state/store.go:25-27 defines a schema bump as one the prior Core cannot safely reopen. Because this decision provides only an offline restore while ftw is API-only, the promised unattended fallback instead becomes an outage requiring host intervention. Require staged data or automatic launcher restoration of the verified backup before starting the old Core.

AGENTS.md reference: AGENTS.md:L24-L25

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed. Fixed in e4ab278: decision 13 now says a failed schema-changing trial must not start the previous Core on migrated data. The launcher restores the verified backup before it starts previous, with no operator action, and the rollout evidence covers that case.

frahlg added a commit that referenced this pull request Sep 24, 2026
The owner runs native updates on the machine (ADR 0007 as amended in
#1373). ftw-cli ships in the release package and the installer puts it
on PATH as /usr/local/bin/ftw, owned by root. It talks only to the
local Core API, asks nothing and never starts Core:

- status: version, published release, last run, previous release,
  health and history, with the systemd commands to look next
- update [--channel]: follows a run already in progress, waits
  through the restart, reports what runs and how health settled;
  already current exits 0; stops before a state-schema change
- rollback: binary rollback to previous, followed the same way
- backup [--output-dir]: verified archive, copy checked by SHA-256
- support: the redacted zip, rejected if the stream was cut

Every request has a timeout and waiting is bounded by the trial
deadline. doctor, startup, the channel prompt, --port and Core's
-port flag are gone, and the Core binary no longer routes update.

A native "restarting" status now stays in flight until the trial
deadline instead of failing after five minutes. The bind error asks
/api/health, so a starting Core is recognised, and names ftw status.

The native web panel reports version, release, command and last run
without controls; it shows a loading panel before the first check and
fetches nothing for the old dialog. Setup on native names ftw update
instead of offering Update now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7
The previous Core cannot safely reopen migrated state, so decision 2's
automatic fallback must not start it on that data. The launcher
restores the verified backup before it starts previous, and the
rollout evidence covers that case.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7
@frahlg
frahlg merged commit a5e074e into master Sep 24, 2026
13 checks passed
frahlg added a commit that referenced this pull request Sep 24, 2026
* feat(cli): add ftw update, backup, doctor, support, and startup

A native install's version panel no longer opens the old updater.
ftw update asks beta or stable, or takes --channel. The same command
backs up, checks the running Core, writes a redacted support file, and
prints a systemd snippet to paste. Starting Core on a port FTW already
holds says that it is already running.

* feat(cli): ship ftw as the native operator command

The owner runs native updates on the machine (ADR 0007 as amended in
#1373). ftw-cli ships in the release package and the installer puts it
on PATH as /usr/local/bin/ftw, owned by root. It talks only to the
local Core API, asks nothing and never starts Core:

- status: version, published release, last run, previous release,
  health and history, with the systemd commands to look next
- update [--channel]: follows a run already in progress, waits
  through the restart, reports what runs and how health settled;
  already current exits 0; stops before a state-schema change
- rollback: binary rollback to previous, followed the same way
- backup [--output-dir]: verified archive, copy checked by SHA-256
- support: the redacted zip, rejected if the stream was cut

Every request has a timeout and waiting is bounded by the trial
deadline. doctor, startup, the channel prompt, --port and Core's
-port flag are gone, and the Core binary no longer routes update.

A native "restarting" status now stays in flight until the trial
deadline instead of failing after five minutes. The bind error asks
/api/health, so a starting Core is recognised, and names ftw status.

The native web panel reports version, release, command and last run
without controls; it shows a loading panel before the first check and
fetches nothing for the old dialog. Setup on native names ftw update
instead of offering Update now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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