Conversation
Packaging-layer only — no application source changes. Plumbing - start-sdk 1.5.3 -> 2.0.9. Drops the redundant `await` on the now-lazy `SubContainer.of`, and the Makefile loses its s9pk.mk fallback shim now that the SDK ships s9pk.mk itself. - Collapses `tsconfig.startos.json` and `startos/tsconfig.json` into one file at `startos/tsconfig.json` extending the SDK's tsconfig.base.json. It has to live inside `startos/` — the root tsconfig belongs to the React app, and eslint's projectService needs a project that actually contains `startos/**/*.ts`. - Runs the SDK's eslint gate (`startos:lint`), which the previous Makefile override silently skipped. - Adds the three packaging workflows. Their tag filters and the desktop lane's are made mutually exclusive: `tagAndRelease` tags `v<version>_<revision>`, `scripts/release.sh` tags `v<version>`, and the template's `v*.*` / desktop's `v*` would each have fired on the other's tags. - Adds AGENTS.md + CLAUDE.md, UPDATING.md and TODO.md; un-ignores CLAUDE.md, which every StartOS package repo carries as a one-line `@AGENTS.md` import. - icon.png: 1024x1024/713K -> 512x512/203K. A package icon is embedded as a base64 data URL in every registry index, and this was 3.4x the largest icon in the fleet. Manifest and versions - packageRepo now points at this fork, which is the package repo. - 5.5.0:14 -> 5.7.0:0. The upstream half tracks package.json (5.7.0) and the revision restarts at 0; nothing was ever published under the old string. - description and releaseNotes gain es_ES, de_DE, pl_PL and fr_FR, and translations.ts is populated for all four instead of being an empty stub. Runtime - Readiness now requires each client's wallet bridge port as well as its web port. A client whose bridge is down still served its page and then 502'd every /bridge/ call while reporting healthy. - Adds a read-only Wallet Bridge Status action reporting, per client, whether the bridge answers, whether it has joined a federation, and its relay discovery state — the only visibility StartOS had into the component holding the money was none. - Reframes the interfaces: they were named and described as "isolated testing clients" in a package whose marketplace copy sells a marketplace. - Drops the triplicated proxy-timeout comment in nginx.conf down to one. Docs - README.md is now the StartOS package README the packaging guide prescribes; app build/architecture material is upstream documentation and is linked, not duplicated. instructions.md is rewritten end-user-first, opening at Documentation. - Both document the standing limitation that neither the clients nor the bridges authenticate anyone: the bridge's own non-loopback auth guard is bypassed by serving it through nginx on the page's origin, so whoever can load an interface can spend that client's ecash.
MattDHill
approved these changes
Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Full audit of the StartOS packaging layer ahead of a Community Registry listing. No application source is touched — everything here is under
startos/, the build/CI plumbing, the package docs, and the icon.What changed
SDK and build plumbing
@start9labs/start-sdk1.5.3 → 2.0.9. The only source-level migration 2.0 needs here is dropping theawaitonSubContainer.of, which is now lazy and synchronous. TheMakefilealso loses its fallback shim for locatings9pk.mk— the SDK ships it since 2.0.6, so the Makefile is now the canonical two lines plus one documented recipe override.tsconfig.startos.jsonandstartos/tsconfig.jsonwere duplicates of each other. There is now a singlestartos/tsconfig.jsonthatextendsthe SDK'stsconfig.base.json. It has to live insidestartos/: the roottsconfig.jsonbelongs to the React app and includes onlysrc, and the SDK's ESLint runner usesprojectService, which needs a project that actually containsstartos/**/*.ts.javascript/index.jsoverride skippeds9pk.mk's eslint step.npm run startos:lintis back in the recipe.build.yml,release.yml,tagAndRelease.yml, targetingmain.This repo now has two release lanes tagging the same namespace:
scripts/release.sh)v5.7.0desktop-release.ymltagAndRelease.yml)v5.7.0_0release.ymlLeft alone, the packaging template's
v*.*would have fired the s9pk release on every desktop tag, anddesktop-release.yml'sv*would have fired a full Tauri build on every packaging tag (and then failed its own gate, sincev5.7.0_0doesn't matchpackage.json). Sorelease.ymlfiltersv*_*anddesktop-release.ymladds!v*_*. These two must stay in sync — noted inAGENTS.md.Manifest, versions, i18n
packageRepo→https://github.com/Start9-Community/chama(this fork is the package repo).upstreamRepostill points atjesuspirate/chama.5.5.0:14→5.7.0:0: the upstream half trackspackage.json, and the revision restarts at 0 because the upstream version moved. Nothing was ever published under the old string —chamais absent from both community registries — so this is a clean initial release.translations.tswas an empty{}stub; it now carrieses_ES,de_DE,pl_PL,fr_FRfor every index, and the manifestdescription(short + long) andreleaseNotescarry the same locales. Every user-facing string inmain.ts,interfaces.tsandactions/flows throughi18n().Runtime
/bridge/call. It now requires each client's bridge port too, and names the client in the failure message.wallet-status, read-only, running-only). Reports per client whether the bridge answers, whether it has joined a federation, and its relay-discovery state. StartOS previously had zero visibility into the component that holds the money.nginx.conf: the same five-line proxy-timeout rationale was pasted into all three server blocks; it is stated once now.Docs and assets
README.mdis now the package README the packaging guide prescribes (centered logo, upstream callout, TOC, the full prescribed section set, AI-consumer YAML block, no version numbers anywhere). The app's build/architecture material is upstream documentation, so it is linked rather than duplicated.instructions.mdrewritten end-user-first: opens at## Documentation, no install steps, no restatement of the marketplace description, no StartOS-platform explainers.AGENTS.md,CLAUDE.md,UPDATING.md,TODO.md.CLAUDE.mdwas removed from.gitignore— every StartOS package repo carries it as a one-line@AGENTS.mdimport. Your other local agent-memory files (Codex.md,PHILOSOPHY.md,DECISIONS.md,INVARIANTS.md,BACKLOG.md,.claude/) stay ignored. Say the word if you'd rather keepCLAUDE.mdlocal and I'll drop it.icon.png1024×1024 / 713 KB → 512×512 / 203 KB. A package icon is embedded as a base64 data URL in every registry index, and this was 3.4× the largest icon in the fleet. The Makefile rule that re-copied the full-size Tauri mark is gone;AGENTS.mdrecords the one-line command to regenerate it.assets/ABOUT.md→assets/.gitkeep. It was never mounted, so it shipped inside the.s9pkas dead weight.Known limitation, documented not fixed
Neither the clients nor the bridges authenticate anyone.
chama-fedimint-bridgerefuses a non-loopback bind without--auth-token("an unauthenticated bridge is a drainable wallet"), but here it is reached through nginx on the same origin as the page, so whoever can load a client interface can spend that client's ecash. A packaging-side token would be injected by the same nginx that serves the page, so it would add nothing. This is now stated in the README's Limitations, ininstructions.md, and inTODO.mdas something that needs an application-side fix.Test plan
Built and verified on a real StartOS box (x86_64, StartOS 0.4.0-beta.10).
Then, on the box:
start-cli package list→chama 5.7.0:0 installed;start-cli package start chama.start-cli db dump | jq .value.packageData.chama.statusInfo→
{"health":{"primary":{"name":"Web Clients","result":"success","message":"All three Chama clients are ready"}}}start-cli package attach chama -n chama-sub -- cat /proc/net/tcpshows0.0.0.0:8080/8081/8082and127.0.0.1:8787/8788/8789.curl -k https://<host>:<assigned-ssl-port>/on each →200,<title>Chama — Bitcoin commerce for communities</title>./bridge/proxy reaches its own bridge.curl -k https://<host>:<port>/bridge/healthon each →200with that bridge's health JSON.start-cli package attach chama -n chama-sub -- ls /data→client-1 client-2 client-3, and each bridge runs with its own--data-dir.start-cli package action run chama wallet-status <<< 'null'→ all three clients reportFederation: Not joined yet(correct for a fresh install) andRelay discovery: Reachable.chama-fedimint-bridgetook the whole daemon down (primary daemon crashed), StartOS restarted it, all three bridges came back and health returned toAll three Chama clients are ready.The app's own gates also pass with the bumped dependency:
npm run typecheck,npm test(all suites green), andnpm run startos:check/startos:lint.Not exercised:
aarch64(CI builds it), backup/restore, and a real federation join.