Skip to content

fix(startos): audit packaging — drop stale sdk-build, add aarch64, complete i18n - #1

Open
helix-nine wants to merge 1 commit into
mainfrom
audit/startos-packaging-review
Open

fix(startos): audit packaging — drop stale sdk-build, add aarch64, complete i18n#1
helix-nine wants to merge 1 commit into
mainfrom
audit/startos-packaging-review

Conversation

@helix-nine

@helix-nine helix-nine commented Jul 30, 2026

Copy link
Copy Markdown

Full audit of the StartOS packaging ahead of Community Registry listing. This fork maintains only the StartOS wrapper: it consumes the image upstream publishes and never builds or pushes one of its own. Changes are confined to startos/, the build files, and CI — no application code is touched, so the fork stays cleanly rebasable on upstream.

What was broken

sdk-build/ shipped stale duplicate source. Its build script copied startos/*.ts in before bundling, but 19 of those copies were also committed, frozen at version 0.1.1:0 and image tag 0.5.2 while startos/ said 0.5.3. Deleted; the package now builds startos/ directly.

CI was publishing container images from this fork. Both release.yml and test-build.yml built the app and pushed it to ghcr.io/<this repo>. This fork maintains only the StartOS wrapper, so both jobs are gone: each workflow now just packs an s9pk against the tag named in the manifest, and nothing in CI writes to a container registry.

That also removes a destructive bug. test-build.yml rebuilt the released tag as amd64-only on every push to main and force-pushed it over the multi-arch image, plus :latest — which is why 0.5.2 in GHCR has no arm64 layer while 0.5.3 still does.

The manifest locked out ARM. arch: ['x86_64'], although the published 0.5.3 image is genuinely amd64 + arm64 — which excluded every ARM server. Now ['x86_64', 'aarch64'], verified by packing the aarch64 s9pk.

A dead duplicate setInterfaces in index.ts. start-core reads only main/init/uninit/createBackup/manifest/actions from the bundle, so it was never invoked. Restored to canonical plumbing.

Four version files with no-op migrations. v0_4_2/v0_4_7/v0_5_0/v0_5_2 all had empty up. Removed, other: []. The packed manifest still reports canMigrateFrom: "<=0.5.3:1", so every prior install upgrades in one hop.

The alerts block no longer exists in SDK 2.0. It passed typecheck only because setupManifest infers its generic from the argument, and was discarded at pack time regardless. Removed.

The marketplace long description was factually wrong — it advertised "BraiinsOS+ / CGMiner API", predating the asic-rs rewrite.

i18n was a scaffold, not an implementation. translations.ts was an empty stub. Now es_ES/de_DE/pl_PL/fr_FR across all six keys, plus those locales on the manifest descriptions and release notes.

startos/README.md was a dead scaffold citing a manifest.yaml that does not exist and StartOS 0.4.0.x. Rewritten against the packaging guide's writing-readmes.md; instructions.md rewritten against writing-instructions.md.

Also: SDK 2.0.62.0.9, main.ts defers to the image CMD via sdk.useEntrypoint() instead of duplicating it, packageRepo points at this fork, and stale release steps corrected in CONTRIBUTING.md and CLAUDE.md.

Known limitation, now documented

The service writes nothing to its mounted volume. All user state — miner list, names, captured power ceilings, and saved miner API passwords — lives in the browser's localStorage (blisspoint.state.v2). So main mounts at /data and stays empty, and Backups.ofVolumes('main') captures nothing: a restore yields an empty miner list. Confirmed empirically on the box. Changing it is an application decision, so this PR documents it prominently in both the README limitations and the user-facing instructions rather than leaving the backup silently implying it works.

Test plan

Verified on a real StartOS 0.4.0.1 box (x86_64):

  1. make x86 → builds and packs blisspoint_x86_64.s9pk at v0.5.3:1, sdk 2.0.9. make arm also packs, confirming the arm64 image resolves.
  2. start-cli package install -s blisspoint_x86_64.s9pk → installs as 0.5.3:1.
  3. start-cli package start blisspoint → daemon starts; logs show Blisspoint serving on :80.
  4. Health check goes green: {"result": "success", "message": "The web interface is ready"}.
  5. Inside the container: node server/serve.cjs on 0.0.0.0:80 and proxy-rs on 127.0.0.1:8081 only.
  6. LAN egress works — the container reached a host and the gateway on the local /24. This is the whole premise of the service.
  7. GET /api/scan?subnet=<lan> swept a real /24 and returned cleanly.
  8. Web UI reachable over the LAN through the StartOS gateway; SPA fallback and /api/health both work end-to-end.
  9. stop is immediate and clean (no PID-1 signal hang, so runAsInit is not needed); start returns to green.
  10. /data confirmed empty after install, start, restart and a scan.

Not covered: miner control itself — pause/resume and power-target were not exercised against real hardware, as no ASIC was available on the test network. The transport around them is verified; the control paths are not.

…mplete i18n

This fork maintains only the StartOS wrapper: it consumes the image upstream
publishes and never builds or pushes one of its own. Changes are confined to
startos/, the build files, and CI; no application code is touched.

Build:
- Delete sdk-build/. Its build script copied startos/*.ts in before bundling,
  but 19 of those copies were also committed, frozen at 0.1.1:0 / image tag
  0.5.2 while startos/ said 0.5.3. Build startos/ directly instead: the SDK and
  ncc move to the root package.json as startos:check / startos:build, with the
  packaging tsconfig and a commonjs marker beside the source. The marker is
  load-bearing — the app root is "type": "module", and `s9pk pack` require()s
  the bundle.
- The package cannot use the SDK's s9pk.mk, which needs `npm run build` to be
  the ncc step while here it is the Vite build, so the Makefile stays bespoke.
- Bump @start9labs/start-sdk 2.0.6 -> 2.0.9; pack with an assets dir.

CI — stop publishing images:
- Both release.yml and test-build.yml built the app and pushed it to
  ghcr.io/<this repo>. Drop those jobs entirely; each workflow now only packs
  an s9pk against the tag named in the manifest. Nothing in CI writes to a
  container registry.
- test-build.yml previously rebuilt the released tag as amd64-only on every
  push to main and force-pushed it over the multi-arch image, plus :latest.
  That is how 0.5.2 lost its arm64 layer. Removing the job removes the hazard.
- Release and artifact names now derive from the packed manifest, with ':'
  replaced by '_' since git refs cannot contain it.

Package:
- arch was ['x86_64'] although the published image is amd64+arm64, excluding
  ARM servers entirely. Now ['x86_64', 'aarch64'].
- Drop the alerts block: it no longer exists in the SDK 2.0 types, passes
  typecheck only because setupManifest infers its generic from the argument,
  and is discarded at pack time.
- packageRepo now points at this fork, which is where the packaging lives;
  upstreamRepo and marketingUrl stay on the application's own repo.
- Remove a dead duplicate setInterfaces from index.ts; start-core reads only
  main/init/uninit/createBackup/manifest/actions from the bundle.
- Drop four migration-less version files and set other: []. The packed manifest
  still reports canMigrateFrom "<=0.5.3:1".
- main.ts defers to the image CMD via sdk.useEntrypoint() rather than
  restating it.
- The long description still advertised "BraiinsOS+ / CGMiner API", predating
  the asic-rs rewrite.

i18n: translations.ts was an empty stub. Populate es_ES/de_DE/pl_PL/fr_FR for
all six keys and add those locales to the descriptions and release notes.

Docs: startos/README.md was a scaffold citing a manifest.yaml that does not
exist and StartOS 0.4.0.x; rewritten against writing-readmes.md, with
instructions.md rewritten against writing-instructions.md. Both now state that
no data is written to the mounted volume — all state is browser localStorage,
so backups capture nothing.

Verified on StartOS 0.4.0.1 (x86_64): installs, daemon starts, health green,
UI reachable over LAN, LAN egress from the container works, a real /24 scan
completes, stop/restart clean, /data empty.
@helix-nine
helix-nine force-pushed the audit/startos-packaging-review branch from a4225ad to 30e58eb Compare July 30, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant