# Installer Fix2 Implementation — Arch Detection + Checksum Verification

**Date:** 2026-03-29
**Branch:** culurien

---

## Summary

Added runtime architecture detection and binary checksum verification to both Linux and Windows installer templates. Fixed carry-over Windows config path issue from Fix 1.

## Files Changed

### 1. `windows.ps1.tmpl` — Config path carry-over fix

**Problem:** Template wrote config to `C:\ProgramData\RedFlag\config.json` but the agent reads from `C:\ProgramData\RedFlag\agent\config.json` (canonical path from `constants.GetAgentConfigPath()`).

**Fix:**
- Added `$AgentConfigDir = "C:\ProgramData\RedFlag\agent"` variable
- Changed `$ConfigPath` to use `$AgentConfigDir` instead of `$ConfigDir`
- Added `New-Item -ItemType Directory -Force -Path $AgentConfigDir` to directory creation
- Removed redundant `$ConfigPath` re-assignment in Step 4

### 2. `windows.ps1.tmpl` — Architecture detection

**Added** runtime architecture detection using `$env:PROCESSOR_ARCHITECTURE`:
```powershell
switch ($Arch) {
    "AMD64" { $ArchTag = "amd64" }
    "ARM64" { $ArchTag = "arm64" }
    default { exit 1 }
}
```
Download URL now uses the detected arch: `{{.ServerURL}}/api/v1/downloads/windows-${ArchTag}?version={{.Version}}`

### 3. `windows.ps1.tmpl` — Checksum verification

**Added** SHA256 verification after download:
- Downloads to temp file first, uses `Invoke-WebRequest -PassThru` to capture headers
- Reads `X-Content-SHA256` from response headers
- Uses `Get-FileHash` with `.ToLower()` normalization for comparison
- If checksum present and mismatches: error + exit
- If checksum missing: warn + continue (backward compatible)
- Moves verified binary to install dir after validation

### 4. `linux.sh.tmpl` — Architecture detection

**Added** runtime architecture detection using `uname -m`:
```bash
case $ARCH in
    x86_64)  ARCH_TAG="amd64" ;;
    aarch64) ARCH_TAG="arm64" ;;
    armv7l)  ARCH_TAG="armv7" ;;
    *)       exit 1 ;;
esac
```
Download URL overridden with detected arch: `{{.ServerURL}}/api/v1/downloads/linux-${ARCH_TAG}?version={{.Version}}`

### 5. `linux.sh.tmpl` — Checksum verification

**Added** SHA256 verification after download:
- Downloads to temp file, saves response headers with `curl -D`
- Extracts `X-Content-SHA256` from response headers
- Compares with `sha256sum` output
- If checksum present and mismatches: error + exit
- If checksum missing: warn + continue
- Moves verified binary to install dir after validation

### 6. `downloads.go` — Server-side checksum + arch support

**Checksum header:** Added `computeFileSHA256()` helper function and `X-Content-SHA256` + `X-Content-Length` headers to `DownloadAgent` handler. The checksum is computed on-the-fly from the binary file.

**Arch query param:** `generateInstallScript()` now reads optional `?arch=` query parameter (validated against `amd64`, `arm64`, `armv7`; defaults to `amd64`). This sets the arch in template data, but since templates now auto-detect at runtime, this serves as a fallback/hint.

### 7. `AgentManagement.tsx` — Dashboard updates

Updated platform descriptions to note ARM64 support:
- Linux: "Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux (AMD64 + ARM64)"
- Windows: "Windows 10/11, Server 2019/2022 (AMD64 + ARM64)"

Extensions arrays updated to `['amd64', 'arm64']`.

### 8. `downloads_checksum_test.go` — New tests

3 new tests:
- `TestChecksumComputesCorrectSHA256` — verifies known content produces expected hash
- `TestChecksumIsLowercase` — confirms hex output is lowercase (PowerShell compatibility)
- `TestChecksumEmptyFileProducesValidHash` — confirms empty files produce valid 64-char hash

## Design Decisions

### Arch Detection: Template Runtime vs Server Hint

Both approaches are used:
- **Server-side:** `?arch=` query param on `/install/:platform` endpoint (default `amd64`)
- **Template runtime:** `uname -m` / `$env:PROCESSOR_ARCHITECTURE` overrides the server-suggested download URL

The runtime detection is authoritative because the install script runs on the target machine and knows its actual architecture. The server hint is a fallback for programmatic use.

### Checksum: Warn Not Fail

If the server does not provide the `X-Content-SHA256` header (e.g., old server version), the installer warns but continues. This maintains backward compatibility with servers that haven't been updated.

## Test Results

```
Server: 106 passed, 0 failed (7 packages)
Agent:   60 passed, 0 failed (10 packages)
Total:  166 tests, 0 failures
TypeScript: 0 errors
```

## Manual Test Plan Additions

### Linux Arch Detection
- [ ] Run install on x86_64 — confirm downloads `linux-amd64` binary
- [ ] Run install on aarch64 (Raspberry Pi, ARM VM) — confirm downloads `linux-arm64`
- [ ] Run install on unsupported arch — confirm error message and exit

### Windows Arch Detection
- [ ] Run install on AMD64 Windows — confirm downloads `windows-amd64`
- [ ] Run install on ARM64 Windows — confirm downloads `windows-arm64`

### Checksum Verification
- [ ] Download binary from server — confirm `X-Content-SHA256` header present
- [ ] Corrupt downloaded binary, re-run verification — confirm failure detected
- [ ] Run against server without checksum header — confirm warning but install proceeds

### Windows Config Path
- [ ] Fresh Windows install — confirm config written to `C:\ProgramData\RedFlag\agent\config.json`
- [ ] Registration step reads config from same path

## ETHOS Checklist

- [x] Windows config path fixed in template (carry-over)
- [x] Arch auto-detected in Linux template (uname -m)
- [x] Arch auto-detected in Windows template ($env:PROCESSOR_ARCHITECTURE)
- [x] Server install endpoint accepts optional ?arch= param
- [x] X-Content-SHA256 header served with binary downloads
- [x] Linux installer verifies checksum (warns if missing)
- [x] Windows installer verifies checksum (warns if missing)
- [x] Checksum comparison is lowercase-normalized
- [x] Checksum header test written and passing
- [x] All 166 Go tests pass
- [x] No emoji in new Go server code
- [x] No banned words in new template text
- [x] Backward compatible: missing checksum = warn not fail
