# Changelog All notable changes to Furtka will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, release 0, alpha stage). ## [Unreleased] ## [26.3-alpha] - 2026-04-16 ### Fixed - **Release workflow no longer depends on `jq`.** The previous `apt-get install -y jq` step hung on a slow mirror for 15+ minutes and stalled the 26.2-alpha publish. `publish-release.sh` now assembles the release-create payload via a tiny `python3 -c` block — Python is always available on the Forgejo Actions runner. `apt-get` path removed entirely. ## [26.2-alpha] - 2026-04-16 ### Fixed - **Updater "Check for updates" no longer 404s when every release is a pre-release.** `check_update()` queried Forgejo's `/releases/latest`, which silently excludes pre-releases (anything tagged `-alpha`/`-beta`/`-rc`) and returns 404 when there is no stable release. Switched to `/releases?limit=1`, which Forgejo sorts newest-first across all release kinds. During the alpha stage where every tag is a pre-release this is the only thing that works; once we tag a stable release, the same query still picks it up. ## [26.1-alpha] - 2026-04-16 ### Added - **Furtka self-update** (Phase 2). Tagging a release on main fires `.forgejo/workflows/release.yml`, which packages `furtka/` + `apps/` + a root-level `VERSION` file as `furtka-.tar.gz`, uploads it plus a `.sha256` + `release.json` to the Forgejo releases page, and makes the release available to running boxes. New CLI: `furtka update [--check]` + `furtka rollback`. New endpoints: `POST /api/furtka/update/check` + `/apply` + `GET /api/furtka/update/status`. UI: "Furtka updates" card on `/settings` shows installed vs latest, Update button runs the apply flow detached via `systemd-run`, progress polls `/update-state.json` served by Caddy so the mid-update API restart doesn't interrupt reporting. Atomic `/opt/furtka/current` symlink flip, auto-rollback on health-check failure post-restart, SHA256-verified downloads. - **Per-app container image updates** (Phase 1). `POST /api/apps//update` runs `docker compose pull`, compares the running container's image digest to the just-pulled local image digest per service, and only restarts containers whose image actually changed. Update button on each installed-app row in `/apps`. Keeps `image: :latest` pins simple — no compose-file mutations. - **Per-version install layout** on `/opt/furtka/`. Install now extracts the resource-manager payload to `/opt/furtka/versions//` and creates `/opt/furtka/current` as an atomic symlink; updates flip the symlink in place and `systemctl link` every unit from the shipped `assets/systemd/` tree. Runtime JSON (`status.json`, `furtka.json`, `update-state.json`) moved to `/var/lib/furtka/` so self-updates never clobber it. - **On-box UI uplevel** across three pages sharing one design system (`/style.css` served by Caddy). Redesigned landing page with a "Your apps" tile grid driven by `/api/apps`, a `fileshare` app tile that deep-links to `smb://.local/files`, status tiles, and subtle "Coming next" links to `furtka.org`. `/apps` page renders real app icons inlined from each manifest's `icon.svg` (defensive SVG sanitiser — strips script/on*/javascript: content, 16 KB cap). New `/settings` page with About-this-box, Appearance, Furtka-updates, and Coming-next sections. Persistent top nav (Jakob's Law) on every page. Light-mode support via `prefers-color-scheme`. - **Webinstaller step 2 (boot drive)** now shows size / type / health chips plus a "Recommended" badge on the auto-selected drive instead of a raw numeric score. - **Forgejo branch protection on `main`** — no direct pushes except owner-whitelisted, required status checks (`CI / lint*`, `CI / test*`, `CI / validate-json*`), applied via the idempotent `ops/forgejo/apply-branch-protection.sh` script. - **In-browser app settings**, so users no longer need SSH + `vim` to configure an app before first install. Manifest gains optional `settings` (name/label/description/type/required/default) and `description_long` fields. Installing a bundled app opens a form rendered from the manifest; installed apps grow a "Settings" button that edits merged values (password fields blank = keep current). API: `POST /api/apps/install` now accepts a `settings` object in the JSON body; new `GET`/`POST /api/apps//settings` for inspecting and updating an installed app. Password values never leave the server. - `nano` added to the installer package list so users have a beginner-friendly editor at the console/SSH (was `vim`-only, which `command not found`'d under Arch 4.x because it was actually missing from the package set too). - `openssh` added explicitly to the installer package list and `sshd` added to enabled services. `archinstall: true` in archinstall 4.x did not actually install openssh-server, so the documented recovery path (SSH → edit `.env`) silently failed. - **Forgejo Actions runner** live on Proxmox VM (`forge-runner-01`, Ubuntu 24.04) with DinD sidecar — CI green end-to-end. Setup scripts in `ops/forgejo-runner/`. - **Walking-skeleton live ISO** (`iso/build.sh`). Overlays an Arch `releng` profile with Flask + the webinstaller, bakes a systemd unit that auto-starts the wizard on boot, produces a hybrid BIOS/UEFI ISO via `mkarchiso` in a privileged `archlinux:latest` container. Tested booting under OVMF in Proxmox — wizard screens 1–3 respond at `http://:5000`. - **Public website at [furtka.org](https://furtka.org)** (`website/`). Hugo static site, English + German, served from `/var/www/furtka.org` on `forge-runner-01` via nginx. Upstream openresty proxy handles TLS. Intentionally minimal single-page copy while the project is pre-alpha. Deploy is `./website/deploy.sh` (rsync + remote Hugo build); one-time VM setup in `ops/nginx/setup-vm.sh`. ### Changed - Every on-box asset (landing page, settings page, style.css, status/welcome scripts, systemd units, Caddyfile) moved from inline Python string constants in `webinstaller/app.py` into real files under `furtka/assets/`. The installer reads them from disk at install time; the self-updater ships them in the release tarball. - Settings-button label went from "Einstellungen" (prototyping leftover) to "Settings" — rest of the UI chrome is English. - Keyboard layout at the TTY now follows the chosen installer language (`de` → `de`, `pl` → `pl`, `en` → `us`) instead of hardcoding `us`. Previously German users couldn't type `/`, `-`, or `=` at the recovery console. - `fileshare` app: `description_long` + `settings` (SMB_USER, SMB_PASSWORD) for the new settings form. Docker-level healthcheck from `dperson/samba` is disabled in the compose override — it timed out under normal operation and marked a working share "unhealthy" in `docker ps`. - **Project name finalized: Furtka.** Working title "Homebase" retired. Domain `furtka.org` registered via Strato 2026-04-13. - Managed gateway NS hostnames updated from `ns1.homebase.cloud` / `ns2.homebase.cloud` to `ns1.furtka.org` / `ns2.furtka.org`. - Python package renamed from `homebase` → `furtka` in `pyproject.toml`. ## [26.0-alpha] - 2026-04-13 First tagged snapshot. Pre-alpha — the installer does not yet boot, but the design is locked and the prototype components are shaped. ### Added - **Installer webapp prototype** (`webinstaller/`) — Flask app with 3-step wizard (hostname → drive → overview), serves drive list via `drives.py::list_scored_devices()`. - **Drive scoring module** (`webinstaller/drives.py`) — scores attached disks by type (NVMe/SSD/HDD), SMART health (`smartctl -H`), and size. Consumed by the installer and usable as a CLI. - **Base archinstall configuration** (`archinstall/user_configuration.json`) — systemd-boot, ext4, Docker + Compose preinstalled, server profile, SSH. Credentials template at `archinstall/user_credentials.example.json` (real credentials gitignored). - **Installer wireframes** (`docs/installer-wireframes.md`) — Robert's hand-drawn 4-screen UX sketches. - **Competitor analysis** (`docs/competitors.md`) — CasaOS, Umbrel, YunoHost reviewed across install flow, hardware detection, app store UX, reverse proxy/SSL, user complaints. Key finding: device-aware wizard + managed gateway are uncontested differentiators. - **Wizard flow spec** (`docs/wizard-flow.md`) — 8-screen first-boot flow extending Robert's wireframe with YunoHost-style domain/SSL/diagnostic/confirm screens. Locked tech picks with rejected alternatives. - **Project README** — vision, principles, architecture, key decisions, landscape, roadmap. ### Decisions locked - **Reverse proxy:** Caddy (auto Let's Encrypt, simplest config) - **Identity provider:** Authentik (bundled SSO, every app auto-wired at install) - **Managed gateway DNS:** NS delegation to `ns1.furtka.org` / `ns2.furtka.org` (wildcard cert via Let's Encrypt DNS-01) - **Local HTTPS:** Local CA installed by user once (no browser warnings on `*.proksi.local`) - **Base OS:** Arch (rolling, Debian remains fallback) - **Containers:** Docker + Compose - **License:** AGPL-3.0 [Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.3-alpha...HEAD [26.3-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.3-alpha [26.2-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.2-alpha [26.1-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.1-alpha [26.0-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.0-alpha