Commit Graph

15 Commits

Author SHA1 Message Date
2a163bb9e7 fix(linux/build): install sq-git/Sequoia stack for derivative-maker (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m21s
Run #4255 reached deeper into 1100_sanity-tests, finished its apt-get
phase, and then died at the supply-chain verification step:

    /workspace/.../help-steps/git_sanity_test: line 184: sq-git: command not found
    ERROR: sq-git verification failed: main repo
    INFO: If this is intentional, configure your own sq-git policy file.
          See 'buildconfig.d/30_signing_key.conf'.

derivative-maker uses sq-git (sequoia-git) to authenticate the commit
chain against an OpenPGP policy file before building. The policy file
itself ships in the upstream repo (./openpgp-policy.toml) and the
trust-root defaults are correctly configured by help-steps/variables
(line 232 + 290) for non-redistributable builds — i.e. the verification
machinery is fully wired and just needs the binary.

Aligns with the upstream container's package list at
linux/build/derivative-maker/docker/derivative-maker-docker-setup.

Changes:
- Dockerfile.builder: add sq, sqv, sqop, sequoia-git,
  sequoia-chameleon-gnupg, gpg-agent. All available in trixie main.
- build.sh: BUILDER_IMAGE digest re-pinned to sha256:c1490bab…5c97
  (rebuilt on 10.0.0.51, sq-git binary verified present at /usr/bin/sq-git).

No reproducibility implications — image rebuilds against the same
pinned snapshot timestamp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:31:03 +01:00
433eb18947 fix(linux/build): bump builder base bookworm → trixie (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m19s
Run #4254 finally got past every harness issue and into derivative-
maker's actual sanity-tests, where it died with:

    You are attempting to build on an unsupported operating system or version.
    detected operating system codename: 'bookworm'
    expected operating system codename: 'trixie'

The pinned derivative-maker tag (18.1.7.4-developers-only) requires
Debian 13 (trixie) as the build host. Upstream's own
linux/build/derivative-maker/docker/Dockerfile uses
`FROM debian:trixie-slim`. We picked bookworm originally and the tag
mismatch wasn't caught until the build actually ran.

Changes:

- Dockerfile.builder: FROM debian:bookworm-slim →
  debian:trixie-slim @ sha256:cedb1ef4…2c5a (resolved 2026-05-07 on
  the runner host). sources.list suite names follow:
  `bookworm` → `trixie`, `bookworm-security` → `trixie-security`.
  snapshot.debian.org pin (20260415T000000Z) is unchanged — snapshots
  are date-keyed, so the same timestamp resolves trixie's dists/.
- silvermetal-base.conf: DERIVATIVE_DIST `bookworm` → `trixie` for
  consistency (the value isn't passed to derivative-maker — there's
  no --dist option — but it's referenced by the build.sh prologue
  and we shouldn't have a stale codename floating around).
- build.sh: BUILDER_IMAGE digest re-pinned to sha256:7d893178…1890
  (rebuilt natively on 10.0.0.51 against the new base, pushed).

The reproducibility guarantee is unchanged in shape — same snapshot
timestamp, same source-date-epoch derivation, just a different stable
host OS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:25:40 +01:00
4a3971cb06 fix(linux/build): correct derivative-maker CLI invocation (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m13s
Run #4253 finally got past all the harness failures and into
derivative-maker's actual build steps, where 1100_sanity-tests
rejected our invocation with:

    unknown option (1): '--build'

The CLI we'd been passing was built from invented flag names rather
than the real grammar in derivative-maker/help-steps/parse-cmd.
Concretely:

  - `--build`  is not a real option (just wrong)
  - `--flavour` should be `--flavor` (upstream uses American spelling)
  - `--dist`   is not a real option; dist is implicit from `--flavor`
                (kicksecure-cli ⇒ bookworm)
  - `--config` is not a real option; the silvermetal-base.conf is
                sourced into env above the invocation, no flag needed
  - `--freedom true|false` was missing entirely; parse-cmd requires it
                for `--arch amd64` (line 70 in parse-cmd) — the script
                exits if neither is set

Fix: build-inner.sh now invokes
    ./derivative-maker --flavor … --target … --arch … --freedom …
which is the minimal valid form per parse-cmd's case-branches.

Set DERIVATIVE_FREEDOM=false in silvermetal-base.conf, matching
Kicksecure's own public-ISO choice — `--freedom true` would omit
firmware-nonfreedom and the resulting ISO wouldn't initialise wifi /
many GPUs / Intel microcode on most hardware. Privacy/functionality
trade-off documented inline; the hardening overlay in M1.2+ can
revisit if that conversation becomes useful.

Verified: bash -n on both scripts. No image rebuild needed — pure
script and config changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:18:38 +01:00
bf55a3f81c fix(linux/build): mark build-inner.sh executable (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m14s
Run #4252 died at:

    runuser: failed to execute /workspace/SilverLABS/SilverMetal/linux/build/scripts/build-inner.sh:
    Permission denied

The script was created on the WSL/Windows side (/mnt/c) where every
file appears world-rwx regardless of git's index, so the local
`chmod +x` was a no-op as far as git was concerned and the file got
committed at mode 100644 like any other regular file. Sibling scripts
(build.sh, verify-reproducibility.sh, diagnose-divergence.sh) all
correctly carry 100755 in the index.

Fix: `git update-index --chmod=+x` to set the bit in the index
explicitly, independent of the working-tree perms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:13:02 +01:00
b20e568b19 fix(linux/build): run derivative-maker as unprivileged builder user (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m14s
Run #4251 advanced past checkout and into derivative-maker, then died
immediately:

    ERROR: This must NOT be run as root (sudo)!
    ERROR: Exiting ./derivative-maker with non-zero exit code 1.
           Errors Detected: 0. Execution Time: 00:00:00.

Kicksecure's derivative-maker explicitly refuses to run as root — it
expects a regular user with passwordless sudo and uses sudo internally
for the privileged operations (debootstrap, mksquashfs, chroot mounts).
Our minimal debian-slim builder image had a `builder` user (uid 1000)
but no sudo, no sudoers entry, and the container ran as root.

Aligns with the upstream Kicksecure container pattern at
linux/build/derivative-maker/docker/derivative-maker-docker-setup
(uses USER=user with `${USER} ALL=(ALL) NOPASSWD:ALL`).

Changes:
- Dockerfile.builder: install `sudo` (and `fakeroot` while we're here —
  upstream sanity-tests pulls this in via apt at build time, but having
  it baked avoids a snapshot.debian.org round-trip every run); add
  passwordless sudoers entry for builder; correct the misleading
  comment that claimed root was needed.
- New scripts/build-inner.sh: the inner derivative-maker invocation
  pulled out of build.sh's heredoc. Once we needed to drop privileges
  via runuser, the nested-heredoc / nested-quoting situation became
  unmaintainable; a regular script with normal quoting is far cleaner.
- build.sh: inner heredoc now just chowns the workspace to builder and
  runuser's into build-inner.sh. ${REPO_ROOT} and ${BUILD_DIR} continue
  to be forwarded into the container via -e.
- build.sh: BUILDER_IMAGE digest re-pinned to sha256:f8f0db37…1bedc
  (rebuilt and pushed natively on 10.0.0.51 — never on the WSL/aarch64
  dev box, see reference_silvermetal_runner.md memory).

Verified: bash -n on both scripts; image builds and pushes cleanly.
Pushing this commit triggers a fresh CI run that will exercise it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:09:42 +01:00
1d0e58739c fix(linux/build): handle DooD bind-mount in CI (M1.1)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 1m18s
build.sh ran fine locally but failed in Gitea Actions on the first
reproducibility-gated run (#4250) with:

    bash: line 3: /work/linux/build/config/silvermetal-base.conf:
    No such file or directory

Root cause: classic Docker-out-of-Docker confusion. build.sh runs
inside the act_runner job container, which talks to the host's docker
daemon via the mounted /var/run/docker.sock. The "-v ${REPO_ROOT}:/work"
flag was being interpreted by the host daemon against the host
filesystem, where /workspace/SilverLABS/SilverMetal does not exist;
docker silently auto-created an empty dir there and mounted that as
/work, so the config source target was missing.

Fix: detect GITHUB_ACTIONS and use --volumes-from "$(hostname)" in CI
to inherit the parent job container's /workspace mount intact. Locally
we keep a bind mount, but use the same path inside and outside
(${REPO_ROOT}:${REPO_ROOT}) so the inner heredoc is identical in both
modes. Inner script now references "${REPO_ROOT}/..." and
"${BUILD_DIR}/..." instead of the synthetic /work and /out paths.

No reproducibility implications — bind topology doesn't affect bytes
inside the ISO.

Verified locally: bash -n passes; structural change only, behaviour
preserved for the non-CI path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:01:06 +01:00
eae2b98906 fix(linux/build): re-pin BUILDER_IMAGE to amd64 registry digest
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 11s
Two corrections to f9e606d:

1. Registry hostname: docker-registry:5000 isn't DNS-resolvable on the
   SLAB docker host (verified). The fleet-wide convention is the canonical
   docker-registry.silverlabs.uk URL, registered as an insecure-registry
   in /etc/docker/daemon.json on every docker host.

2. Architecture: the original push from WSL2-on-aarch64 produced an arm64
   image that won't run on the amd64 runner. Rebuilt natively on the docker
   host. New manifest digest (amd64-only):
     sha256:9e7161f9f180483f434074d7f32c27c907955232bd0c44efe6dc0ee1d9e56ae0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:59:52 +01:00
7b99516232 feat(linux/build): silvermetal-builder Gitea Actions runner deployment
act_runner-based deployment that handles `runs-on: silvermetal-builder` jobs.
Adapted from the stinky-roger-tv flutter-builder pattern with three changes:

- privileged: true (live-build needs loop devices + chroot)
- 4h job timeout (covers two reproducibility-gated ISO builds + diffoscope)
- silvermetal-builder label maps to catthehacker/ubuntu:act-latest, not the
  silvermetal-builder image — the builder image stays minimal (no docker-cli),
  and build.sh invokes it via `docker run` from the catthehacker job shell

Deployed at /opt/silvermetal-builder-runner/ on the SLAB docker host
(10.0.0.51); registered with git.silverlabs.uk and reporting healthy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:59:44 +01:00
f9e606d22d fix(linux/build): pin BUILDER_IMAGE to pushed registry digest (M1.1)
Image built from Dockerfile.builder@36f7672 was pushed to both
docker-registry:5000 (internal) and docker-registry.silverlabs.uk
(external) under tags m1.1-bootstrap + latest. Both URLs serve the
same registry, so the manifest digest is identical:

  sha256:cedef039425e0b0f5901c1023eda820c7aa38ab4b81c2bb1e12d64cadb3d6c85

Default points at the internal hostname for CI; external dev overrides
via BUILDER_IMAGE env var.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:48:48 +01:00
36f7672c6f fix(linux/build): make builder image actually build (M1.1)
- Pin debian:bookworm-slim by real digest (resolved 2026-04-26).
- Two-phase install: seed ca-certificates from the default mirror first
  so HTTPS to snapshot.debian.org works, then swap to the pinned snapshot
  for the toolchain itself. Slim images don't ship the CA bundle, so the
  one-shot pinned-source-only install would deadlock on cert verification.

Validated locally: image builds clean, 302MB, all live-build / debootstrap /
mksquashfs / xorriso / diffoscope-minimal present.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 04:49:34 +01:00
4444dc11f3 feat(linux/build): scaffold reproducible ISO build pipeline (M1.1)
Vendors Kicksecure derivative-maker as a pinned submodule (18.1.7.4),
adds the wrapper + verify + diagnose scripts, the pinned builder image,
and the reproducibility-gated Gitea Actions workflow. Base flavour only —
no hardening overlay (that's M1.2).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 04:25:48 +01:00
810301908d docs(hardware): capture Coreboot SKU shortlist for Phase 1.13 hardware pilot
Three viable vendors today for a UK-based hardened-laptop reseller program:
Star Labs (UK), NovaCustom (NL), System76 (US). Recommended 3-SKU lineup:

- Tier 1 / Lite: Star Labs StarBook Horizon (Alder Lake-N, ME disabled,
  ~£1,140) — UK domestic, no Heads option
- Tier 2 / Pro: NovaCustom V54 (Meteor Lake, Dasharo + factory Heads,
  ~£1,210) — flagship; B2B reseller programme + custom engraving
- Tier 3 / Workstation: NovaCustom V56 (Meteor Lake + optional dGPU,
  ~£1,250+) — Qubes-certified, dual NVMe, 96 GB RAM ceiling

Key findings:
- Framework not yet shipping factory Coreboot for non-Chromebook (AMD
  openSIL port still in development per Phoronix Mar 2026); revisit Q4 2026
- Purism Librem 14 ruled out — old CPU, supply unreliable
- AMD PSP cannot be cleanly disabled in shipping firmware in 2026 — Intel
  with neutered ME wins for the hardened tier; revisit when Star Labs
  StarFighter AMD or Framework AMD Coreboot ports stabilise (~2027)
- NovaCustom is the strongest single partner: Clevo B2B reseller
  programme, factory-flashed Heads option, free UPS to UK, custom-logo
  engraving available

Operational cautions documented: Meteor Lake S0ix suspend caveat with ME
disabled (default to hibernate-only), EC firmware not 100% open anywhere
(don't market as "fully libre"), Dasharo firmware ships quarterly so
re-verify before each procurement batch.

Snapshot dated 2026-04-25; all source URLs cited for human verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 03:41:49 +01:00
acd3ebe7f2 docs(chat): adopt existing SilverVPN.Client.Chat as SilverChat — promote to v1
Inspection of ../SilverVPN/clients/SilverVPN.Client.Chat reveals a mature,
production-grade SilverChat implementation:

- Cross-platform MAUI client (Windows / macOS / Android / iOS)
- 13 ViewModels + 13 Views — feature-complete UX (contacts, conversations,
  group chat, invites, safety numbers, settings, login)
- Signal Protocol crypto: Double Ratchet, X3DH (PreKey + Identity stores),
  Safety Numbers, encrypted attachments
- VpnChatTransport — chat carried over the SilverVPN tunnel itself,
  eliminating third-party metadata exposure
- Server-side already in SilverVPN.Api: ChatHub (SignalR), ChatController,
  ChatAttachmentController, ContactsController
- Windows MSI installer wired (installer/silverchat/SilverChat.wxs)

Decision: adopt-as-is, do not duplicate. SilverChat is more advanced than
the v1.1 plan (which considered Matrix / Signal-fork) — three wins:
1. Signal Protocol natively, not a tentative fork
2. Chat over the VPN tunnel — better metadata hygiene
3. Cross-platform on day one

Changes:
- stack/chat/README.md rewritten as integration pointer (mirror of stack/vpn/)
- stack/README.md status table updated; SilverChat promoted v1.1 → v1
- docs/roadmap.md: new milestone 1.9 (Chat integration into Linux v1);
  Phase 1.1 alignment-review milestone removed (resolved by this finding);
  remaining 1.1 milestones renumbered
- root README.md: Stack table + Status table updated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 03:38:45 +01:00
0a0075ce66 docs(naming): adopt OS / Enhanced product-line framing + align with existing repos
Two product lines, named to make scope obvious to buyers:
- 🔒 SilverMetal OS — we ship the operating system or ROM
  (Linux, Pixel, Samsung-unlocked, Motorola-unlocked)
- 🛡️ SilverMetal Enhanced — we harden the OS the device already runs
  (Windows, macOS, iOS, generic Android)

Repo alignment:
- SilverVPN already exists as a SilverLABS product (server + MAUI client +
  Linux client + tunnel service). stack/vpn/ is now an integration pointer
  rather than a re-scaffold; per-platform READMEs reference it.
- SilverApple is deprecated; SilverMetal Enhanced — iOS supersedes it.
  Migration step added as roadmap milestone 3I.1.
- SilverDROID name clash explicitly noted as unrelated (it's the SilverSHELL
  AppStore Android client, not an Android ROM).
- SilverChat may overlap with SilverVPN.Client.Chat; alignment decision
  added as roadmap milestone 1.1.1.

Roadmap restructured: phases now track the OS/Enhanced split.
Platform matrix re-sectioned and decision flowchart updated.
README rewritten around the two-product-line framing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 03:30:45 +01:00
7d5f9cc246 chore(scaffold): initial SilverMetal program scaffold
Cross-platform privacy-hardening program. Two-layer product:
- SilverLABS Application Stack (cross-platform spine)
- Platform Hardening Profiles (per-OS, tier-honest)

Platforms: Linux (Debian/Kicksecure), Android (Pixel/Samsung/Moto/generic),
Windows (LTSC IoT), macOS (profile), iOS (MDM profile). Each flavour has
both a preflashed hardware SKU path and a self-apply "harden your existing
device" path.

Includes umbrella docs (README + threat-model, design-principles,
platform-matrix, roadmap, trust-model), per-platform and per-stack-
component README stubs, .gitignore, LICENSE.

Linux v1 ships first; Stack v1 = Browser + VPN + Sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 03:11:48 +01:00