# Spec Delta ## MODIFIED Requirements ### Requirement: Public installer endpoint The app SHALL serve an installer script at `/fpagent/install.sh` that is reachable without authentication. When run, the script SHALL determine the host's architecture, fetch the latest release metadata, choose the bundle for the host architecture, verify the bundle's published sha256 checksum, extract it, and hand off to the extracted bundle's own installer. It SHALL prefer a bundle built for the host's distro codename when one exists for that architecture, and otherwise use the generic bundle for that architecture. The script SHALL be served uncached. #### Scenario: Installer is fetched anonymously - **WHEN** a client requests `/fpagent/install.sh` without a session - **THEN** the app returns the installer script and does not redirect to login #### Scenario: Host-appropriate bundle is chosen - **WHEN** the latest release offers both a bundle for the host's Ubuntu codename and a generic bundle - **THEN** the installer uses the codename bundle #### Scenario: Generic bundle is the fallback - **WHEN** the latest release offers no bundle matching the host's Ubuntu codename - **THEN** the installer uses the generic bundle #### Scenario: Bundle matches the host architecture - **WHEN** the latest release offers a bundle for the host architecture and a bundle for another architecture - **THEN** the installer chooses the bundle for the host architecture - **AND** it never chooses a bundle for another architecture #### Scenario: 32-bit host uses the 32-bit bundle - **WHEN** the installer runs on an i386 host and the release offers only a generic 32-bit bundle - **THEN** the installer uses that generic 32-bit bundle #### Scenario: Checksum is verified before extraction - **WHEN** the installer downloads a bundle and its published checksum - **THEN** it verifies the checksum before extracting and refuses to install when the checksum does not match #### Scenario: Options are forwarded to the bundled installer - **WHEN** the installer is invoked with options such as `--no-service` or `--check` - **THEN** it passes those options through to the extracted bundle's installer #### Scenario: No compatible bundle - **WHEN** the latest release contains no bundle for the host architecture - **THEN** the installer exits with a failure message that names the host architecture and installs nothing #### Scenario: Unsupported architecture - **WHEN** the installer runs on a machine whose architecture is neither x86_64 nor i386 - **THEN** it exits with a failure message and installs nothing ### Requirement: Installed version is tracked and upgrades are reported The installer SHALL treat the git hash in the bundle's asset name as the version, for every architecture it can install. It SHALL hand that version to the bundle installer, which SHALL record it beside the installed binary and SHALL report an upgrade with the previous and new versions on the next run. Uninstalling SHALL remove the recorded version. #### Scenario: Version is derived from the asset name - **WHEN** the installer selects a bundle named `fpagent--.tar.gz` - **THEN** it uses `` as the version #### Scenario: Version is derived for a 32-bit bundle - **WHEN** the installer selects a generic bundle named `fpagent--linux-i386.tar.gz` - **THEN** it uses `` as the version #### Scenario: Upgrade is reported - **WHEN** the recorded version differs from the version being installed - **THEN** the bundle installer reports the change from the old to the new version #### Scenario: First install records the version - **WHEN** no version has been recorded yet - **THEN** the bundle installer records the new version and reports no upgrade #### Scenario: Uninstall removes the recorded version - **WHEN** the installer is asked to uninstall - **THEN** the recorded version is removed