LocalSky 0.1.0 Launch Checklist
Source of truth for what has to be true before silenthooligan/localsky is flipped public and tagged v0.1.0. Read top to bottom. Do not skip steps.
The fork model is: silenthooligan/localsky is the public canonical repo. aperturelabs/aperturelabs-localsky-deploy is the private overlay that mounts the homelab .env and points Komodo at the public GHCR image. See migration.md for the mechanics.
Phase 1 - Secrets rotation (do this first)
Any credential that has ever touched the internal git history is treated as leaked.
- Revoke the current
HA_LONG_LIVED_TOKENfrom the HA UI; mint a new one and store it only inaperturelabs-localsky-deploy/.env - Regenerate the VAPID keypair; old public key retired from every active subscriber; new keys in the private overlay only
- Mint a new fine-grained GitHub PAT scoped only to
silenthooligan/localsky(read/write contents, packages, actions). Stash asGHCR_PATin the private overlay - Rotate the OpenSprinkler password MD5 if it has ever been committed
- Do not reuse the
ghp_*PAT documented inaperturelabs-core-manager/secrets.md- that one is scoped for Renovate and HACS, not for this repo
Phase 2 - Code + repo hygiene (on the v2 branch)
-
cargo fmt --checkclean -
cargo clippy -- -D warningsclean -
cargo check --features ssrzero warnings -
cargo check --features hydrate --target wasm32-unknown-unknownzero warnings -
cargo test --features ssrall passing (157+ as of 2026-05-20) -
cargo deny checkclean - No
Co-Authored-By: Claudetrailer anywhere in v2 commit history - No em dashes in README, CHANGELOG, CONTRIBUTING, SECURITY, or any doc that ships to the public site
Phase 3 - Sanitize for public
The scrub script lives at scripts/sanitize-for-public.sh. It produces a clean tree in /tmp/localsky-seed/.
- Run
scripts/sanitize-for-public.sh; review the output -
grep -rEi '192\.168\.|skean\.net|aperturelabs|omega-|LXC|VLAN|10\.1\.100' /tmp/localsky-seed/returns zero matches - No
.env(only.env.example) - No
.gitea/directory - No
_shared/,data/,target/,dist/,*.pem -
Dockerfileuses non-root user (useradd --uid 10001 localsky,USER 10001:10001) -
docker-compose.ymlreferencesghcr.io/silenthooligan/localsky:latest, no internal registry refs, env via${VAR}from.env.example -
Cargo.tomlhaslicense = "Apache-2.0",repository = "https://github.com/silenthooligan/localsky",homepage = "https://github.com/silenthooligan/localsky"
Phase 4 - Public repo bootstrap
- Create
silenthooligan/localskyon GitHub (start private) - Single initial commit from the sanitized seed, author
silenthooligan <[email protected]>, message"Initial public release of LocalSky" - Push to
main - Clone fresh into a tmpdir; re-run the grep sweep; zero matches required before flipping to public
- Enable GitHub Discussions
- Verify issue templates render correctly
- Verify pull request template renders correctly
- Verify
SECURITY.mdcontact (set up the forwarder; test message delivers) - Flip repo visibility to public
Phase 5 - Build, scan, ship
- GitHub Actions builds
ghcr.io/silenthooligan/localsky:0.1.0and:latest - Multi-arch:
linux/amd64+linux/arm64 - Trivy scan: zero HIGH+ vulnerabilities
- SBOM published as a release asset
-
docker inspect ghcr.io/silenthooligan/localsky:0.1.0showsUser: 10001 - mdBook docs site builds + deploys to GitHub Pages from the
v0.1.0tag
Phase 6 - Real-world boot tests
Each must pass on a clean machine before tagging v0.1.0.
- Demo boot:
docker run -e LOCALSKY_DEMO=1 -p 8090:8090 ghcr.io/silenthooligan/localsky:0.1.0boots and serves UI; sparkline + zone math visible; cycling verdicts - First-run wizard: no env vars, no
/data/localsky.toml-> boots to/setup/welcomeon both desktop and mobile viewport; completes end-to-end; written TOML is valid; no process exit - Legacy continuity: HA env vars present, no
/data/localsky.toml->env_compatsynthesizes aha_service_callcontroller +ha_passthroughsource; existing/data/irrigation.dbmigrates cleanly (M0001 -> latest); UI identical to v0.1 - Standalone: only
tempest_udp+open_meteoconfigured (no HA, no MQTT) -> dashboard works;/api/healthreportsha: not_configured - Standalone with MQTT:
mqtt_subscribesource pulls soil moisture from an external broker; sensor values land insensor_history - Ecowitt LAN: GW1100 pointed at
http://localsky:8090/ingest/ecowitt; packets ingested and visible in/api/health
Phase 7 - Engine correctness (offline regression)
- Penman-Monteith vs Open-Meteo’s
et0_fao_evapotranspirationon 7 days of recorded Tempest data: RMSE within +/- 0.5 mm/day - Hargreaves fallback vs PM: within +/- 20% (typical bias documented)
- Cycle-and-soak:
(soil=clay, slope=5%, precip=15 mm/hr, runtime=45 min)produces 3 cycles of 15 min + 30 min soaks - Skip-rule replay: load production
verdict_history, replay each row’sinputs_jsonthroughengine::skip_rules-> 100% verdict + reason match on a 30+ day window
Phase 8 - Owner homelab cutover
The private deploy overlay is the only thing that changes on Aperture.
-
aperturelabs-localsky-deployrepo created on internal Gitea withdocker-compose.yml,.env,.gitea/workflows/deploy-komodo.yml, README - Komodo resource sync targets the new repo
- Old
aperturelabs-localskyrepo on internal Gitea marked archived (do NOT delete; v0.1.0 history lives there) - First image pull on LXC 281 succeeds via Gitea webhook -> Komodo
DeployStack - 24-hour stability soak with the public image:
- Tempest UDP bind survives container restart
- Skip-check evaluations stable across the day
- Zone history continuity (no run loss across restart, no duplicates)
-
/api/healthstays green for all configured sources + controllers - No new errors in logs that did not exist on v0.1
Phase 9 - Public release
Only after every box above is checked.
- Tag
v0.1.0onsilenthooligan/localsky - GitHub release notes copy the
[0.1.0]CHANGELOG section verbatim - Cross-arch binary attachments via
cross+softprops/action-gh-release - Cosign keyless OIDC signature on each artifact + the GHCR image
- Hardware compatibility table in README lists only
Testedrows; community + planned rows clearly labeled - At least 5 screenshots in
docs/assets/screenshots/(captured via demo mode) - Announce in (a) personal channels only; do not submit to HN / Reddit / lobste.rs until at least 7 days of soak with no critical bug
Hard “do not ship” conditions
If any of these are true at the planned cutover, do not flip public:
- The grep sweep at the end of Phase 3 returns any match
- Any
cargowarning anywhere - Trivy reports any HIGH+ vulnerability
- The demo mode boot does not serve a full dashboard with cycling verdicts
- The first-run wizard cannot complete without manual TOML editing
- The legacy-continuity boot path does not produce a verdict that matches the v0.1 production verdict for the same day
Post-launch follow-ups (not blocking 0.1.0)
- Hosted demo at
demo.<domain>if a domain is registered - HACS publishing (see hacs.md)
- ESPHome native + Rachio controller adapters (planned 0.2)
- Ambient Weather + Pirate Weather sources (planned 0.2-0.3)
- Telemetry opt-in (Plausible at self-hosted endpoint; version + arch + enabled-adapter-types only)
- axe-core CI job (a11y gate; zero serious violations)