diff --git a/v2/crates/cog-ha-matter/cog/RELEASE-CHECKLIST.md b/v2/crates/cog-ha-matter/cog/RELEASE-CHECKLIST.md new file mode 100644 index 00000000..9f3d6d3f --- /dev/null +++ b/v2/crates/cog-ha-matter/cog/RELEASE-CHECKLIST.md @@ -0,0 +1,79 @@ +# cog-ha-matter Release Checklist + +Mechanical steps to publish a new version. **Everything local-side is +automated; the four "🔑 USER ACTION" blocks below are the only manual +gates.** Each one is a credential-bearing step the cog/ pipeline cannot +do on its own. + +## 1. Pre-release (local) + +```sh +# Bump version in v2/crates/cog-ha-matter/Cargo.toml then: +cargo test -p cog-ha-matter --no-default-features --lib # 64+ tests must pass +cargo check -p cog-ha-matter --no-default-features # green +``` + +## 2. Tag the release + +```sh +git tag cog-ha-matter-v$(cargo pkgid -p cog-ha-matter | sed -E 's/.*#//') +git push origin --tags +``` + +The push fires `.github/workflows/cog-ha-matter-release.yml` which: + + * builds `cog-ha-matter-x86_64` + `cog-ha-matter-arm` (cross-compiled + via apt-installed `gcc-aarch64-linux-gnu`) + * computes SHA-256 sidecars + * runs the Ed25519 sign step **if** `COGNITUM_OWNER_SIGNING_KEY` is set + * uploads workflow artifacts (always — these are downloadable from + the run page) + * uploads to `gs://cognitum-apps/cogs/{arch}/` **if** the org var + `HAS_GCP_CREDENTIALS == 'true'` and the `GCP_CREDENTIALS` secret is set + +## 3. Update app-registry.json + +Take `cog/app-registry-entry.json` from this directory, fill in the +post-build values, and PR it into the [`cognitum-one`](https://github.com/ruvnet/cognitum-one) +repo at `app-registry.json`. + +Values to fill in: + + * `version` — bump to match the new tag + * `sha256` — paste from the workflow artifact's `.sha256` sidecar + * `binary_size` — bytes of the binary (`wc -c < cog-ha-matter-x86_64`) + +## 🔑 USER ACTION items (cannot be automated) + +| # | What | Why this can't be automated | +|---|---|---| +| 1 | Set the `HAS_GCP_CREDENTIALS` org variable to `true` and provision the `GCP_CREDENTIALS` GitHub Actions secret with a service-account JSON that has `storage.objectAdmin` on `gs://cognitum-apps/cogs/` | Requires org-admin access + a GCP project owner's signoff | +| 2 | Provision `COGNITUM_OWNER_SIGNING_KEY` GitHub secret with the Ed25519 private key in PEM form | Long-lived secret material; humans must rotate it; same blocker for cog-pose-estimation | +| 3 | `gcloud auth login` (only if running `make upload` locally instead of via CI) | Browser OAuth flow | +| 4 | File a PR in `cognitum-one` against `app-registry.json` adding the entry from `cog/app-registry-entry.json` | Cross-repo write requires the user's GitHub auth + reviewer signoff | + +## Post-release verification + +Once the cognitum-one PR merges and the cache rolls over (~hourly): + +```sh +curl -sS https://storage.googleapis.com/cognitum-apps/app-registry.json \ + | jq '.[] | select(.id == "ha-matter")' +``` + +Should print the new entry. On the Seed UI, the cog appears under +**Settings → Cogs → building → Home Assistant + Matter Bridge**. + +## Reverting a bad release + +Cogs ship via GCS object versioning (per ADR-100). To roll back: + +```sh +gsutil ls -a gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64 +# Pick the previous generation, then: +gsutil cp gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64# \ + gs://cognitum-apps/cogs/x86_64/cog-ha-matter-x86_64 +``` + +Then PR a `version` bump in `cognitum-one`'s `app-registry.json` so +Seeds know to refetch. diff --git a/v2/crates/cog-ha-matter/cog/app-registry-entry.json b/v2/crates/cog-ha-matter/cog/app-registry-entry.json new file mode 100644 index 00000000..83b4c931 --- /dev/null +++ b/v2/crates/cog-ha-matter/cog/app-registry-entry.json @@ -0,0 +1,71 @@ +{ + "id": "ha-matter", + "name": "Home Assistant + Matter Bridge", + "category": "building", + "version": "0.3.0", + "size_kb": 12, + "difficulty": "easy", + "description": "Exposes WiFi-CSI sensing as Home Assistant entities over MQTT auto-discovery, with mDNS announcement on _ruview-ha._tcp and tamper-evident Ed25519-signed audit logs. Adds 10 semantic primitives (someone_sleeping, possible_distress, fall_risk_elevated, ...) on top of the 11 raw measurements. Privacy mode strips biometrics at the wire so only the semantic layer reaches HA — the right default for any deployment with non-tenant occupants.", + "featured": false, + "config": [ + { + "key": "sensing_url", + "type": "string", + "label": "Sensing server URL", + "description": "Where the cog reads VitalsSnapshot from", + "default": "http://127.0.0.1:3000", + "cli_arg": "--sensing-url" + }, + { + "key": "mqtt_host", + "type": "string", + "label": "MQTT broker host", + "description": "External mosquitto / HA Core MQTT host (v0.7 will add an embedded broker option)", + "default": "127.0.0.1", + "cli_arg": "--mqtt-host" + }, + { + "key": "mqtt_port", + "type": "integer", + "label": "MQTT broker port", + "default": 1883, + "min": 1, + "max": 65535, + "cli_arg": "--mqtt-port" + }, + { + "key": "privacy_mode", + "type": "boolean", + "label": "Privacy mode", + "description": "Strip biometrics at the wire — only semantic primitives are published. Recommended for any deployment with non-tenant occupants (care homes, education, shared housing).", + "default": false, + "cli_arg": "--privacy-mode" + }, + { + "key": "mdns_hostname", + "type": "string", + "label": "mDNS hostname", + "description": "Must end with .local. per RFC 6762. HA's discovery integration looks up this hostname.", + "default": "cog-ha-matter.local.", + "cli_arg": "--mdns-hostname" + }, + { + "key": "mdns_ipv4", + "type": "string", + "label": "Advertised IPv4", + "description": "LAN-routable address the mDNS responder advertises. HA reaches back to this for MQTT.", + "default": "127.0.0.1", + "cli_arg": "--mdns-ipv4" + }, + { + "key": "no_mdns", + "type": "boolean", + "label": "Disable mDNS", + "description": "Skip the mDNS responder. Useful in containerised setups where multicast is filtered.", + "default": false, + "cli_arg": "--no-mdns" + } + ], + "sha256": "", + "binary_size": 0 +}