Commit Graph

91 Commits

Author SHA1 Message Date
sysadmin
4435f6e1c4 fix(welcome): redirect WebView2 data dir off Program Files + launch wizard elevated via scheduled task
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 09:43:46 +01:00
sysadmin
b1226d2bed fix(welcome): extract wizard components to Razor Class Library so bUnit tests don't load WindowsAppSDK (fixes CI DllNotFound on clean runner)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Successful in 4m30s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 08:12:37 +01:00
sysadmin
ee3528f360 ci(welcome): fail the build if the Welcome payload isn't baked (guard against green-but-broken image)
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 1m17s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 04:02:50 +01:00
sysadmin
f39823339f ci(welcome): pin .NET 9 SDK via setup-dotnet so MAUI workload band matches 2026-06-09 03:54:18 +01:00
sysadmin
0b1057d0fa ci(welcome): build + test the Welcome solution before the ISO build 2026-06-09 03:50:35 +01:00
sysadmin
bafdf88fa9 feat(welcome): build bakes the published Welcome app + flavours into the image
Adds Invoke-PublishWelcome (dotnet publish win-x64 self-contained, runs pre-mount)
and Copy-WelcomePayload (copies publish output + flavours/*.json into $mount while
install.wim is open) called from Invoke-ServiceWim's try block. Both are gated on
SILVERMETAL_WELCOME_ENABLED != '0' (enabled by default). Hardening staging unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 03:46:02 +01:00
sysadmin
5715e55694 feat(welcome): SetupComplete defers hardening to Welcome when present 2026-06-09 03:41:45 +01:00
sysadmin
efdaffa73f feat(welcome): bootstrap auto-login launches the Welcome app
Rename the unattend LocalAccount from silvermetal → sm-bootstrap
(Administrators), add a one-time AutoLogon and a FirstLogonCommands
entry that launches SilverOS.Welcome.App.exe on first boot. The
Welcome app's ApplyService tears down AutoAdminLogon + removes
sm-bootstrap on successful onboarding.
2026-06-09 03:36:46 +01:00
sysadmin
346abc3676 fix(welcome): apply re-entrancy guard, scrub error output, lock nav during apply, offline-bundle fonts
- ApplyStep: guard StartAsync against double-invocation (_running check at top)
- ApplyService: replace raw StdErr dump with scrubbed message (exit code + first non-empty line, ≤200 chars)
- ApplyStep: SanitiseForDisplay strips newlines and caps error at 200 chars before rendering
- ApplyStep: add OnRunningChanged EventCallback<bool>; Routes.razor disables Back while _applyRunning
- Routes.razor: AdvanceToDone uses _stepTitles.Length - 1 instead of magic literal 5
- app.css: replace Google Fonts CDN @import with local @font-face rules; bundle DM Mono (300/400/500 + italic 300) and Inter (300/400/500) latin woff2 files under wwwroot/fonts/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 03:34:34 +01:00
sysadmin
ea5adacac3 feat(welcome): apply step wiring + Mercury styling
Wire ApplyStep with public StartAsync(), IProgress<ApplyProgress> marshalled
via InvokeAsync(StateHasChanged), OnComplete EventCallback (host advances to
Done), and failure surface + Retry button. Add _Imports.razor Apply using.
Wire Routes.razor AdvanceToDone handler. Add Mercury CSS: slate-void palette,
DM Mono typography, layered radial gradients, staggered step-enter animation,
styled wizard chrome/cards/fields/progress bar/buttons. 17/17 tests green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 03:20:39 +01:00
sysadmin
a393ded7c6 fix(welcome): touched-gated account errors, flavour-load retry, flavour Next-gate, drop dead inject 2026-06-09 03:12:41 +01:00
sysadmin
1630bde1ee feat(welcome): wizard steps + flavour selection UI
Six wizard step components (Welcome/Flavour/Account/Prefs/Apply/Done),
Routes.razor wizard host with Next/Back navigation and IFlavourLoader
wiring, bUnit FlavourStepTests (TDD red→green), AccountStep field
validation (username/password/admin-password required; BitLocker PIN
numeric ≥6 digits). Test project upgraded to Razor SDK /
net9.0-windows10.0.19041.0 + UseMaui=true to reference the MAUI app
assembly. Non-Windows platform folders removed; demo pages removed.
All 14 tests pass (13 existing + 1 new bUnit).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 03:03:13 +01:00
sysadmin
1f8ada3a45 feat(welcome): MAUI Blazor app skeleton + DI wiring
Adds SilverOS.Welcome.App (net9.0-windows10.0.19041.0 only), registers
all Core services in MauiProgram.cs, and introduces WizardState scoped
service for the wizard host.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 02:50:42 +01:00
sysadmin
b1b278bb8d fix(welcome): correct -Modules arg encoding so hardening subset actually runs (+ real integration test)
powershell.exe -File binds a single-quoted comma list like '00','03','05' as ONE string element,
not a [string[]] array, so Invoke-Hardening.ps1's -contains filter matched nothing and all
hardening modules were silently skipped.

Fix: adopt a CSV-split contract — Invoke-Hardening.ps1 now accepts [string]$Modules and splits
on ',' internally ($ModuleList = $Modules -split ','); ApplyService passes a bare CSV token
(e.g. 00,03,05) with no surrounding quotes. Empirically verified via ProcessStartInfo: candidate
(a) '00','03','05' → COUNT=1 (bug); candidate (b) 00,03,05 → single string, correctly split by
the script; candidate (c) space-separated → PS positional-parameter error. PARSE OK confirmed.

Adds ApplyServiceHardeningIntegrationTests: copies the real Invoke-Hardening.ps1 into a temp
dir with harmless dummy 0*.ps1 stubs, runs ApplyService with the real ProcessRunner for modules
["00","05"], and asserts ran.txt contains RAN 00 and RAN 05 but NOT RAN 03 or RAN 07.
Test fails on the old encoding and passes with the fix (regression-checked).
2026-06-09 02:46:00 +01:00
sysadmin
8fe577e0bf feat(welcome): ApplyService orchestrator (modules->accounts->bitlocker->teardown) 2026-06-09 02:33:39 +01:00
sysadmin
3be703d5c9 fix(welcome): escape bootstrapUser + assert daily user is not admin 2026-06-09 02:30:35 +01:00
sysadmin
62f66490d1 feat(welcome): account + BitLocker + bootstrap services 2026-06-09 02:26:35 +01:00
sysadmin
64b9e3c5f4 feat(welcome): Invoke-Hardening accepts -Modules subset + -ParamsJson 2026-06-09 02:22:04 +01:00
sysadmin
017eaf4d96 feat(welcome): process runner abstraction 2026-06-09 02:18:52 +01:00
sysadmin
6f454fe957 feat(welcome): author Daily-Driver/Privacy-Max/Journalist/Developer flavours 2026-06-09 02:15:46 +01:00
sysadmin
dd1e5faf9c feat(welcome): flavour loader + validation 2026-06-09 02:11:58 +01:00
sysadmin
c49e1802a1 feat(welcome): flavour manifest model 2026-06-09 02:07:58 +01:00
sysadmin
5f0bc5553a feat(welcome): solution + Core/Test project skeleton 2026-06-09 02:04:14 +01:00
sysadmin
dfbf1d1ec8 docs(windows): SilverOS Welcome app implementation plan
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m1s
16-task, 5-phase TDD plan: flavour engine (manifest/loader/4 flavours) -> apply
orchestrator (parameterised Invoke-Hardening, account/BitLocker/bootstrap services,
ApplyService) -> MAUI Blazor wizard -> bootstrap/build integration (autounattend
AutoLogon, SetupComplete defers to Welcome, build bakes app+flavours, CI) -> VM e2e.
Daily account = Standard + SilverOS Admin; Daily-Driver default; Stack stubbed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:53:41 +01:00
sysadmin
9c65c1c3a0 docs(windows): Welcome spec revisions per review
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m50s
- Daily account defaults to Standard User (least-privilege) + separate SilverOS
  Admin elevation account; single-admin model demoted to an option.
- Hardened baseline applies to ALL flavours (none unhardened); Daily-Driver is the
  default/recommended (balanced middle), Privacy-Max is opt-in strictest.
- Name confirmed: SilverOS Welcome. Stack installs remain gated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:47:45 +01:00
sysadmin
b5cfd26f5f docs(windows): SilverOS Welcome app spec (v1)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m42s
First-logon Blazor Hybrid (MAUI) onboarding app: bootstrap auto-login -> wizard
(persona->flavour, account + BitLocker PIN, prefs) -> apply via the existing §A-H
PowerShell modules per a JSON flavour manifest -> create real account, enrol
BitLocker, self-destruct bootstrap. Resolves the repo-throwaway-password and
interactive-PIN gaps. v1 = interactive auto-launch only; silent pre-baked mode +
fleet enrolment + Linux-shared model deferred.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:41:48 +01:00
sysadmin
638d08696d feat(windows): set local-account creds + UK keyboard/region
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m33s
- Local admin password -> "open sesame" (still a placeholder for the public repo;
  SKU pipeline must replace per-device).
- UK keyboard (InputLocale 0809) + UK region/formats (SystemLocale/UserLocale
  en-GB). Display UILanguage stays en-US because the eval media is en-US and lacks
  the en-GB display pack -- true en-GB display needs en-GB LTSC media or an injected
  language pack (future build step).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:14:08 +01:00
sysadmin
a0b9c2c989 fix(windows/hardening): tolerate missing hibernation (module G)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m51s
VM run: `powercfg /hibernate on` writes to stderr where hibernation is unsupported
(VMs), which under ErrorActionPreference=Stop aborted module G after its earlier
lock-screen settings applied. Wrap it so the module completes cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:46:13 +01:00
sysadmin
ba3ef0d45a fix(windows): hardening modules never ran (SetupComplete quoting bug)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m12s
VM runtime test (offline disk mount) revealed SetupComplete.cmd ran but its inline
multi-line `powershell -Command` (cmd ^-continuation + nested escaped quotes) failed
to parse ("string is missing the terminator") -> the §A-H modules never executed.
Offline CI assertions only proved the files were BAKED, not that they RUN.

Fix: move the module runner into hardening/Invoke-Hardening.ps1 and call it with
-File (no cmd quoting). Runner runs 00*..08* in order then Verify (writes
verify-report.json in-line as SYSTEM; reboot/PIN-dependent gates show pending).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:34:05 +01:00
sysadmin
d690b14fc4 feat(windows): automate OOBE region/keyboard (oobeSystem International-Core)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m33s
VM run reached OOBE but the region/keyboard pages were still interactive: the
oobeSystem pass lacked Microsoft-Windows-International-Core, so 24H2 OOBE
(CloudExperienceHost) prompted for them even under legacy Setup. Add it +
HideOEMRegistrationScreen + HideLocalAccountScreen so OOBE is fully hands-off to
the local account / desktop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:16:49 +01:00
sysadmin
448de1c570 fix(windows/build): revert to prompt boot image (no-prompt caused reinstall loop)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m29s
The no-prompt efisys + media-first boot order reboot-loops: every post-copy reboot
re-boots the media before the disk install completes, so it never finishes (symptom:
"no bootable device" after ejecting). Standard efisys.bin (press-any-key) lets reboots
fall through to the installed disk. Legacy-Setup boot.wim patch + /unattend retained
(the real fix). Documented VM-verified result + the residual one-click WinPE language
page in iso-builder.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:58:12 +01:00
sysadmin
17b2ec2be7 fix(windows/build): launch legacy Setup with explicit /unattend
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m47s
Legacy Setup (forced via boot.wim CmdLine) still showed the language page because
implicit answer-file search is unreliable when setup is launched via CmdLine. Inject
autounattend.xml into boot.wim (X:\autounattend.xml) and set CmdLine to
"X:\sources\setup.exe /unattend:X:\autounattend.xml" so all passes are consumed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:31:37 +01:00
sysadmin
5e6303d48e feat(windows): force legacy Setup on 24H2 to fix hands-off install
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 4m15s
VM test proved Win11 24H2 redesigned "ConX" Setup ignores the windowsPE pass of
autounattend.xml (manual language/keyboard/region prompts). Deep-research-verified
fix: patch sources\boot.wim index 2 to launch the legacy installer.

build.ps1 stage 2b: mount boot.wim idx2, load offline SYSTEM hive, set
HKLM\SYSTEM\Setup\CmdLine=X:\sources\setup.exe, unload, commit. Also place
autounattend.xml in \sources as well as ISO root. Legacy engine consumes all
four passes -> fully hands-off. Documented in iso-builder.md §3a (incl. rejected
winpeshl.ini / RunSynchronous alternatives + ConX-may-change caveat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:20:37 +01:00
sysadmin
b4d303cbaa feat(windows): unattended install — noprompt boot + disk config (M2)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m25s
VM boot test proved the ISO boots under UEFI+SecureBoot+TPM2 but stopped at the
"press any key" prompt and (post-boot) the disk screen. Enable hands-off install:
- build.ps1: use efisys_noprompt.bin (fall back to efisys.bin) so the ISO boots
  without a keypress.
- autounattend.xml: add GPT/UEFI DiskConfiguration (wipe disk 0 -> EFI/MSR/Win),
  ImageInstall index 1, AcceptEula (eval = no key). Bootstrap local-admin pw is a
  PLACEHOLDER the SKU pipeline must replace.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:55:47 +01:00
sysadmin
d26595d26f ci(windows): persist validated ISO to stable runner path
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m23s
RUNNER_TEMP is ephemeral; copy the validated build output to C:\silvermetal\out\
so it can be retrieved out of band (e.g. for VM boot-testing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:42:16 +01:00
a6afc604c5 Merge pull request 'ci(windows): M2 ISO build + Gitea Windows-runner workflow' (#3) from ci/build-iso-windows into main
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (push) Failing after 19s
2026-06-08 20:13:11 +00:00
sysadmin
6d23a892b9 ci: remove throwaway runner-probe/runner-prep diagnostics
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 1m51s
Their job is done (runner topology mapped, C: extended, ISO staged). The build
+ offline-validation pipeline is green on the runner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:13:06 +01:00
sysadmin
5dbbaaf22c fix(windows/build): drop oscdimg -bootdata inner quotes (PS arg mangling)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Successful in 3m24s
Stages 1-5 pass; oscdimg failed with Error 123 because PowerShell doubled the
embedded quotes in -bootdata. Work paths have no spaces, so omit the inner
quotes around etfsboot.com/efisys.bin entirely.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:08:33 +01:00
sysadmin
3effd5e338 ci(windows): pin base-ISO SHA + verify; ISO staged locally on runner
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 1m55s
Base eval ISO staged at C:\silvermetal\base.iso on GITEA-RUN-WIN (SHA256
2CEE70BD...CB29 pinned in inputs.manifest.json). Repo var now points at that
local path, so the build reads locally - no NAS share auth / no CI creds.
Dropped -SkipInputVerify so the build verifies the pinned hash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:58:07 +01:00
sysadmin
ee34b8e373 ci: probe credential-less net use as SYSTEM (stored cmdkey)
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 4s
2026-06-08 20:54:33 +01:00
sysadmin
78d4d84f88 ci: runner-prep workflow (extend C: only); drop in-CI ISO staging
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 4s
Master creds must not live in this public repo's Actions, so ISO staging is
handled out-of-band. runner-prep now only extends C: into the resized virtual
disk. Quoted the step name (trailing-colon YAML fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:47:56 +01:00
sysadmin
cc01675056 ci: add throwaway runner-probe workflow to discover runner topology
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 4s
Temporary diagnostic to see the silverlabs-runner-win host identity, drives,
share mounts/stored creds, and ISO reachability before wiring the base-ISO
source. Removed once the source is settled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:33:37 +01:00
sysadmin
5e42da619e ci(windows): make base-ISO acquire step path-aware (UNC/local + optional SMB creds)
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 4s
SILVERMETAL_BASE_ISO_URL now accepts an HTTP(S) URL or a UNC/local path. For a
UNC share that the SYSTEM-context runner can't read anonymously, optional repo
secrets SILVERMETAL_ISO_SHARE_USER/_PASS map the share root via net use first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:19:40 +01:00
sysadmin
1c886deca3 ci(windows): implement M2 ISO build + Gitea Windows-runner workflow
Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 34s
Implement build.ps1 (M2): mount/extract the base ISO, offline-service
install.wim (inject GPD drivers if staged, debloat appx, bake SetupComplete.cmd
+ hardening modules into \Windows\Setup\Scripts), inject autounattend.xml,
oscdimg UEFI repack, emit SHA-256 + SBOM. Elevation + oscdimg guarded.

Add .gitea/workflows/build-iso-windows.yaml: runs on the self-hosted
silverlabs-runner-win (windows-latest), ensures ADK Deployment Tools, acquires
the base ISO from repo var SILVERMETAL_BASE_ISO_URL or a pre-staged path, builds,
validates the baked payload offline, uploads SBOM/SHA (+ISO on dispatch/tag),
attaches to a Gitea release on win-v* tags. Mirrors build-iso-linux.yaml.

Add tests/Assert-IsoStructure.ps1: the no-nested-virt CI gate - mounts the built
ISO + install.wim read-only and asserts autounattend.xml, SetupComplete.cmd, and
the hardening modules are correctly baked. Full QEMU boot+Verify is a follow-on.

Switch autounattend to Windows' native SetupComplete.cmd auto-run (SYSTEM, end
of setup) instead of a duplicate FirstLogonCommands call.

Untested until first runner execution (dev box is ARM64). All PS parse-clean;
autounattend XML + workflow YAML valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 18:11:05 +01:00
d58aa3ec17 Merge pull request 'docs(windows): Enhanced-Windows hardening spec (GPD Pocket 4 reference)' (#2) from docs/enhanced-windows-hardening-spec into main 2026-06-08 14:45:15 +00:00
sysadmin
3a30a0421e docs(windows): add ISO-builder design + scaffold the windows/ tree
Add windows/iso-builder.md: reproducible custom-packed-ISO pipeline design for
SilverMetal Enhanced - Windows on IoT Enterprise LTSC. Covers the licensing
frame (IoT = blessed channel for preinstalled custom images; self-apply stays a
builder), 7 build stages (verify/extract/DISM-service/inject-unattend/brand/
oscdimg-repack/attest), the offline-vs-first-boot-vs-firmware control split, an
honest reproducibility scope (pinned inputs + SBOM + attestation, NOT bit-
identical on Windows), and M0-M4 milestones.

Scaffold windows/ per the planned layout:
- installer/  build.ps1 (7-stage orchestrator, stages stubbed to M2),
              inputs.manifest.json (pinned-input schema), autounattend.xml
              (local-account OOBE), oem/SetupComplete.cmd (first-boot runner)
- hardening/  shared §A-H PowerShell modules + Verify-SilverMetalWindows.ps1
              (used by BOTH the ISO first-boot path and the self-apply track).
              BitLocker module enforces TPM+PIN and blocks TPM-only.
- policies/ wdac/ debloat/ stack-installer/ drivers/ tests/  scaffolded with
  READMEs; wdac/ documents audit->enforce; debloat/ flags Tiny11/NTLite as an
  anti-pattern; rename applocker/ -> wdac/ realised.

All 11 PowerShell scripts parse clean; manifest JSON + autounattend XML valid.
Module bodies are M1 scaffold (safe: log + policy-set; interactive/firmware
steps documented, not faked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:35:13 +01:00
sysadmin
ea2de4339d docs(windows): add Enhanced-Windows hardening spec (Pocket 4 reference)
Add windows/hardening-spec.md: the detailed config-layer hardening spec for
SilverMetal Enhanced - Windows, with the GPD Pocket 4 (AMD Strix Point) as
reference device. Eight control domains (provisioning, boot/firmware trust,
data-at-rest, kernel/credential isolation, app control, network/radios,
physical/lock-screen, privacy/update) each with verification commands, a
buyer-facing residual-risk statement, and one-off -> SKU productization notes.

Refine the windows/README.md v1 scope to match, grounded in the 2026-06-08
deep-research assessment:
- BitLocker TPM+PIN (never TPM-only) - PIN defeats the faulTPM-class offline
  fTPM attack that is literally a BitLocker VMK extraction
- WDAC (App Control), kernel-enforced, audit-first then enforce, as primary;
  AppLocker demoted to fallback (rename planned applocker/ -> wdac/)
- Telemetry at GP+service+firewall layers, NOT hosts-file blocking of MS
  domains (that breaks Windows Update; violates "update or die")
- Add VBS/HVCI/Credential Guard/Kernel DMA Protection to scope + verify gates
- Note Enterprise (prototype) vs IoT Enterprise LTSC (SKU target) equivalence

Bound by docs/threat-model.md and docs/design-principles.md; nation-state /
firmware tier explicitly NOT claimed on consumer UMPC silicon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:19:37 +01:00
303f602d38 fix(linux/build): keep file handle open through TF patch loop (M1.1 iter38)
All checks were successful
Build SilverMetal Linux ISO (reproducibility-gated) / builder-image (push) Successful in 1s
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Successful in 35m9s
Run #4285 hit:

    Traceback (most recent call last):
      File "<stdin>", line 26, in <module>
    ValueError: seek of closed file

iter37's Python heredoc had the search/seek/write loop OUTSIDE the
`with open(...) as f:` block — the file closes when the `with` body
finishes, and `data = f.read()` was the only statement inside it.
Indent the loop inside the with-suite. No semantic changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:06:45 +01:00
6bafa85231 fix(linux/build): byte-patch Rock Ridge TF dates after xorriso (M1.1 iter37)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / builder-image (push) Successful in 1s
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 17m27s
Run #4284's diagnostic (iter36) confirmed xorriso ignores every
date-setting command we throw at it for the node it just -updated:

    flag=0x0e  →  CREATION + MODIFICATION + ACCESS (short form)
    CREATION   (set from source file btime via touch -d):
        7e 05 08 00 2c 3a 00     (= SOURCE_DATE_EPOCH)
    MODIFICATION   (still wall-clock):
        A=7e 05 08 01 02 2c 00   B=7e 05 08 01 12 33 00
    ACCESS   (still wall-clock):
        A=7e 05 08 01 02 2c 00   B=7e 05 08 01 12 32 00

Tested across iters 34-36:
  * `-alter_date_r all "=N" /`           — only fixed CREATION (b)
  * `-alter_date all "=N" path` after -update — same
  * `-volume_date c m x f u s "=N"`      — volume-level only
  * `touch -d "@N" "${new_sqfs}"` before — fixed CREATION via btime
  * various orderings, with/without `--` terminators
None override xorriso's wall-clock stamping of MOD/ACCESS at -commit.

Concede that fight and just patch the bytes after xorriso writes the
ISO. We KNOW exactly what's wrong — the TF entry for
/live/filesystem.squashfs has its CREATION slot correct (= 7-byte
ISO9660 short-form encoding of SOURCE_DATE_EPOCH) but MODIFICATION
and ACCESS still hold the post-process commit time. So copy the 7
CREATION bytes over the 7 MODIFICATION bytes and 7 ACCESS bytes.

The patcher (embedded Python, since silvermetal-builder ships
python3):
  * Finds every TF entry header (`54 46 1a 01 0e`) near the
    "filesystem.squashfs" NM tag (96-byte window — anchors both
    ends so we don't touch some other file's TF entry).
  * Copies CREATION (offset +5..+12) onto MODIFICATION (+12..+19)
    and ACCESS (+19..+26).
  * Skips entries already correct (so re-running is a no-op).
  * Reports how many entries were patched.

This is surgical: only the entry we know is broken, and only when
its MOD/ACCESS actually differ from the (known-correct) CREATION.

If the next run still drifts, the diagnostic byte-offset will tell
us where the residual leak is (almost certainly in some volume
descriptor field we haven't covered yet — at which point we extend
the patcher).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 02:22:56 +01:00
60384e70c8 fix(linux/build): explicit -alter_date all on updated squashfs node (M1.1 iter36)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / builder-image (push) Successful in 1s
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 33m27s
Run #4283's enriched diagnostic gave us a precise, low-level reading
of what's still drifting:

    Hex around first ISO divergence:
      flag=0x0e  →  CREATION + MODIFICATION + ACCESS (Rock Ridge TF, short form)
      CREATION:    `7e 05 08 00 06 2d 00`  (=SOURCE_DATE_EPOCH, both A and B )
      MODIFICATION:
        A=`7e 05 08 00 18 10 00`  → 2026-05-08 00:24:16
        B=`7e 05 08 00 28 14 00`  → 2026-05-08 00:40:20
      ACCESS:
        A=`7e 05 08 00 18 0f 00`  → 2026-05-08 00:24:15
        B=`7e 05 08 00 28 13 00`  → 2026-05-08 00:40:19

The MODIFICATION/ACCESS times match the wall-clock minute when each
build's xorriso -commit fired. So:

  * iter35's `touch -d "@${SDE}" "${new_sqfs}"` did nothing for
    mtime — xorriso doesn't propagate the source file's mtime
    through -update.
  * iter34's `-alter_date_r all "=N" /` updated creation (btime →
    Rock Ridge TF CREATION) but not mtime/atime — possibly because
    -update runs at -commit time and re-stamps the node's a/m
    timestamps with the actual write time, after `-alter_date_r`'s
    in-memory update.

Fix: add an explicit, narrowly-scoped `-alter_date all "=N"
/live/filesystem.squashfs --` AFTER `-update` and BEFORE the global
`-alter_date_r`. Per-file alter_date appears to be the last word
xorriso processes against that specific node.

Keep -alter_date_r all and the full -volume_date c/m/x/f/u/s as
belt-and-suspenders.

If this clears, M1.1 reproducibility gate passes. If not, we'll know
xorriso's `-update` is genuinely stamping at commit time independent
of any in-memory date setting, and the move is to skip -update and
do an mkisofs-style full rewrite from the chroot directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:44:58 +01:00