audit: sdk 2.0, disk guardrails, and dependency-contract fixes - #1
Merged
Conversation
Rebuilds the package on start-sdk 2.0.9 and works through the community submission review. SDK 2.0: - drop the `alerts` manifest block, removed in 2.0. It survived silently because setupManifest's generic inference bypasses excess-property checking, so tsc never flagged it - `SubContainer.eager` in main.ts. `SubContainer.of` is lazy in 2.0, so `.rootfs` is a Promise, and the cookie path was interpolating "[object Promise]" into both the daemon ready-check and the stale-cookie removal. Template literals accept any value, so this compiled clean - consume `s9pk.mk` and `tsconfig.base.json` from the SDK rather than the vendored copies, which had drifted three releases behind - repoint CI at Start9Labs/start-technologies (start9labs/shared-workflows is retired) and restore the push trigger on tagAndRelease Disk footprint. The Liquid sidechain is past 80 GB of raw block data and growing tens of GB a year — sampling 900 blocks across the chain puts the last quarter alone at ~55 GB, with recent blocks an order of magnitude larger than mid-history ones. The docs described this as "a few GB". hardwareRequirements has no disk field, so the guardrails are in JS, following bitcoin-core: - `txindex` was enforced on. It is not needed: PeerSwap resolves swap transactions with `getrawtransaction <txid> <verbose> <blockhash>` over a bounded block range (txwatcher/blockchainRpc.go), never by bare txid. It also forbids pruning. It is now a user toggle defaulting off, matching upstream - expose `prune`, disk-aware, defaulting to a pruned target on hosts too small for an archival node. PeerSwap's Liquid CSV window is 60 blocks, so even the 550 MiB floor retains orders of magnitude more history than any consumer reads - add a `disk-space` health check: fails below a few GB free, where elementsd risks corrupting its chainstate, and notifies once per service start while merely low - `hardwareRequirements.ram` gates install on hosts too small to run the daemon - `dbcache` now derives its default from host RAM rather than a fixed 450 MiB Dependency contract: - export `rpcHostId` / `peerHostId` so dependents resolve the address with `sdk.host.getBridgeAddress` instead of the retired `elements.startos:7041` DNS form; `runtime-info` reports the resolved bridge address too - bind and export the P2P port, which `listen=1` already implied but nothing exposed, retiring a dead `peerPort` constant Also: retire the `as Record<string, LangDict>` cast for the `satisfies` form that actually enforces per-locale completeness, add the new strings across all five locales, drop the `as string` casts and the duplicated temp subcontainer in `runtime-info`, sync AGENTS.md to the current package template, and rewrite README/instructions/ABOUT against the packaging guide's checklists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
helix-nine
force-pushed
the
sdk-2.0-audit
branch
from
August 3, 2026 00:49
79801ca to
3e206b7
Compare
StartOS compares hardwareRequirements.ram against the host's RAM in bytes (start-core init.rs stores MemTotal * 1024 * 1024; HardwareRequirements:: is_compatible does a raw < comparison). A literal 4096 therefore declared a 4 KiB floor and gated nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MattDHill
approved these changes
Aug 3, 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.
Community-submission review of Brendan's (@brendio) Elements (Liquid) package, rebuilt on start-sdk 2.0.9. Version
23.3.3:0→23.3.3:1.Land this before the PeerSwap PR — PeerSwap's dependency gate and address resolution both assume these changes.
The disk story
The submitted docs told users to "plan for a few GB and growing (far smaller than Bitcoin mainnet)". Sampling 900 blocks across 60 evenly-spaced points of the chain (tip 3,997,188) puts it at ~85 GB of raw block data today:
Growth is steeply non-linear — recent sample points average 100–235 KB/block, i.e. 150–330 MB/day, or 50–120 GB/year and rising. The package already sets
validatepegin=0, which correctly removes the full-Bitcoin-node requirement; the Liquid chain itself is the remaining cost.hardwareRequirementshas no disk field, so the guardrails are in JS, followingbitcoin-coreas the fleet reference:txindexwas enforced on. It is not needed — PeerSwap resolves swap transactions withgetrawtransaction <txid> <verbose> <blockhash>over a bounded block range (txwatcher/blockchainRpc.go), never by bare txid — and it forbids pruning. Now a user toggle defaulting off, which is also upstream's default.pruneexposed, disk-aware, defaulting to a pruned target on hosts below the archival threshold and clamped to half the disk. Safe with a wide margin: PeerSwap's Liquid CSV window is 60 blocks (onchain/liquid.go), so even the 550 MiB floor holds days of history against a one-hour requirement.disk-spacehealth check —failurebelow a few GB free, whereelementsdrisks corrupting chainstate, plus a notification once per service start while merely low.hardwareRequirements.ramgates install;dbcachenow derives from host RAM.Correctness
SubContainer.ofis lazy in SDK 2.0, so.rootfsis aPromise. The cookie path interpolated[object Promise]into both the daemon ready-check and the stale-cookie removal. Template literals accept any value, sotscwas silent. →SubContainer.eager.alertsmanifest block — removed in SDK 2.0, retained silently becausesetupManifest's generic inference bypasses excess-property checking.listen=1was enforced but the P2P port was never bound, leaving a deadpeerPortconstant. Now bound and exported as ap2pinterface.runtime-infoadvertisedelements.startos— the retired DNS form. It now reports the resolved bridge address, andrpcHostId/peerHostIdare exported so dependents can usesdk.host.getBridgeAddress.Conformity
Vendored
s9pk.mk(three SDK releases stale) deleted in favour of the SDK's;tsconfig.jsonon the 2.0 form; CI repointed from the retiredstart9labs/shared-workflowstoStart9Labs/start-technologieswith thetagAndReleasepush trigger restored;AGENTS.mdsynced to the current package template; theas Record<string, LangDict>cast replaced with thesatisfiesform that actually enforces per-locale completeness (new strings added across all five locales);as stringcasts and a duplicated temp subcontainer removed fromruntime-info; README/instructions/ABOUT rewritten againstwriting-readmes.md/writing-instructions.md.Test plan
Built
x86_64on start-sdk 2.0.9 and installed on StartOS 0.4.0.1.make x86 install, then start the service.RPCgreen ("The Liquid RPC interface is ready"),Liquid Syncloading with a percentage,Disk Spacegreen with real free space (662.3 GB freeon the test box, confirmingdiskusage.check('/')reads the data pool and not a container overlay).configwithpruneset to a non-zero value. Confirmelements.confgainsprune=<n>andtxindex=0(the two are mutually exclusive in Elements;formToFileforces it), and that the enforced keys are intact. Confirm the daemon logsUnsetting NODE_NETWORK on prune mode/Pruning blockstore…on the next start.start-cli package action get-input elements configand confirmprune'smaxis half the disk andtxindex'sdisabledreflects disk size.rpcon 7041 and the newpeeron 7042.runtime-infoand confirm it returns live chain data plus a resolved bridge address (10.0.3.1:7041on the test box), notelements.startos.peerswapwallet is created on first run and pinned withload_on_startup=true.Not verified: a full Liquid sync (~85 GB, many hours — the test node reached ~12%), and
aarch64locally; CI covers the build matrix.🤖 Generated with Claude Code