From 1e469aa336045f3c278dd32f9ec57360aad1dbd2 Mon Sep 17 00:00:00 2001 From: ruv Date: Sat, 23 May 2026 22:55:44 -0400 Subject: [PATCH] cog-ha-matter (ADR-116 P8): scaffold cog/ publishing layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors v2/crates/cog-pose-estimation/cog/ so the Seed runtime treats cog-ha-matter identically — `cognitum cog install ha-matter` behaves like `cognitum cog install pose-estimation`. Files: * cog/manifest.template.json — 9-field manifest with {{VERSION}} + {{ARCH}} slots, hand-edited by the Makefile signer * cog/Makefile — same target set as cog-pose-estimation: build / build-arm / build-x86_64 sign / sign-arm / sign-x86_64 (Ed25519 step is TODO, blocked on COGNITUM_OWNER_SIGNING_KEY provisioning — same blocker as cog-pose-estimation) upload / upload-arm / upload-x86_64 manifest (delegates to `cargo run -- --print-manifest`) release (= build + sign + upload + manifest) verify (sha256sum vs sidecar) clean Adds `mkdir -p dist` to build steps so the gitignored dist/ folder is created on first build. * cog/README.md — what this cog does, layout map, local dry-run instructions, gcloud auth requirements, the JSON snippet to paste into app-registry.json (in the separate cognitum-one repo, not this one) Local dist/ is intentionally not committed: top-level .gitignore matches `dist/` globally, the Makefile creates it on demand. What this commit does NOT do (P8 remaining): * cross-compile build (needs `rustup target add aarch64-unknown-linux-gnu x86_64-unknown-linux-gnu` + linker) * sign the binaries (COGNITUM_OWNER_SIGNING_KEY not provisioned) * gsutil cp to gs://cognitum-apps/ (needs user's gcloud auth) * append to app-registry.json (lives in cognitum-one repo — separate PR there) Next iter: a CI workflow that runs `make build sign verify` on tag-push, so the local-side pipeline is fully exercised even without the production credentials. Co-Authored-By: claude-flow --- v2/crates/cog-ha-matter/cog/Makefile | 83 +++++++++++++++++++ v2/crates/cog-ha-matter/cog/README.md | 71 ++++++++++++++++ .../cog-ha-matter/cog/manifest.template.json | 10 +++ 3 files changed, 164 insertions(+) create mode 100644 v2/crates/cog-ha-matter/cog/Makefile create mode 100644 v2/crates/cog-ha-matter/cog/README.md create mode 100644 v2/crates/cog-ha-matter/cog/manifest.template.json diff --git a/v2/crates/cog-ha-matter/cog/Makefile b/v2/crates/cog-ha-matter/cog/Makefile new file mode 100644 index 00000000..7454b995 --- /dev/null +++ b/v2/crates/cog-ha-matter/cog/Makefile @@ -0,0 +1,83 @@ +# Build / sign / upload pipeline for cog-ha-matter. +# See ADR-100 §"Build pipeline" + ADR-116 §"Phases" for the contract. +# Mirrors cog-pose-estimation/cog/Makefile so the Seed runtime treats +# both cogs identically — `cognitum cog install ha-matter` works the +# same as `cognitum cog install pose-estimation`. + +CRATE := cog-ha-matter +VERSION := $(shell cargo pkgid -p $(CRATE) 2>/dev/null | sed -E 's/.*#([0-9.]+).*/\1/') +GCS_BUCKET := gs://cognitum-apps/cogs + +ARCHES := arm x86_64 + +# --- Build targets --- + +.PHONY: build build-arm build-x86_64 + +build: build-arm build-x86_64 + +build-arm: + mkdir -p dist + cargo build -p $(CRATE) --release --target aarch64-unknown-linux-gnu + cp ../../target/aarch64-unknown-linux-gnu/release/$(CRATE) ./dist/cog-$(CRATE)-arm + +build-x86_64: + mkdir -p dist + cargo build -p $(CRATE) --release --target x86_64-unknown-linux-gnu + cp ../../target/x86_64-unknown-linux-gnu/release/$(CRATE) ./dist/cog-$(CRATE)-x86_64 + +# --- Sign --- + +.PHONY: sign sign-arm sign-x86_64 + +sign: sign-arm sign-x86_64 + +sign-arm: dist/cog-$(CRATE)-arm + sha256sum dist/cog-$(CRATE)-arm | cut -d' ' -f1 > dist/cog-$(CRATE)-arm.sha256 + # Signature: gcloud secrets versions access latest --secret=COGNITUM_OWNER_SIGNING_KEY \ + # | openssl pkeyutl -sign -inkey /dev/stdin -rawin -in dist/cog-$(CRATE)-arm.sha256 \ + # | base64 -w0 > dist/cog-$(CRATE)-arm.sig + @echo "TODO: wire Ed25519 sign step once COGNITUM_OWNER_SIGNING_KEY is provisioned to CI." + +sign-x86_64: dist/cog-$(CRATE)-x86_64 + sha256sum dist/cog-$(CRATE)-x86_64 | cut -d' ' -f1 > dist/cog-$(CRATE)-x86_64.sha256 + @echo "TODO: wire Ed25519 sign step once COGNITUM_OWNER_SIGNING_KEY is provisioned to CI." + +# --- Upload to GCS --- + +.PHONY: upload upload-arm upload-x86_64 + +upload: upload-arm upload-x86_64 + +upload-arm: dist/cog-$(CRATE)-arm + gsutil cp dist/cog-$(CRATE)-arm $(GCS_BUCKET)/arm/cog-$(CRATE)-arm + +upload-x86_64: dist/cog-$(CRATE)-x86_64 + gsutil cp dist/cog-$(CRATE)-x86_64 $(GCS_BUCKET)/x86_64/cog-$(CRATE)-x86_64 + +# --- Manifest --- + +.PHONY: manifest + +manifest: + @cargo run -p $(CRATE) --release -- --print-manifest + +# --- Convenience --- + +.PHONY: release verify clean + +release: build sign upload manifest + @echo "Release pipeline complete for cog-$(CRATE) v$(VERSION)" + +verify: + @for arch in $(ARCHES); do \ + f=dist/cog-$(CRATE)-$$arch; \ + if [ ! -f $$f ]; then echo " MISSING $$f"; continue; fi; \ + actual=$$(sha256sum $$f | cut -d' ' -f1); \ + expected=$$(cat $$f.sha256 2>/dev/null); \ + if [ "$$actual" = "$$expected" ]; then echo " OK $$f ($$actual)"; \ + else echo " FAIL $$f (expected $$expected, got $$actual)"; fi; \ + done + +clean: + rm -rf dist/cog-$(CRATE)-* diff --git a/v2/crates/cog-ha-matter/cog/README.md b/v2/crates/cog-ha-matter/cog/README.md new file mode 100644 index 00000000..cc353896 --- /dev/null +++ b/v2/crates/cog-ha-matter/cog/README.md @@ -0,0 +1,71 @@ +# HA-Matter Cog Packaging + +Build / sign / upload pipeline for `cog-ha-matter`, mirroring the +[`cog-pose-estimation`](../../cog-pose-estimation/cog/) precedent so the +Seed runtime treats both cogs identically. + +See [ADR-100 — Cog Packaging Specification](../../../../docs/adr/ADR-100-cog-packaging-specification.md) +and [ADR-116 — HA-Matter Seed Cog](../../../../docs/adr/ADR-116-cog-ha-matter-seed.md). + +## What this cog does + +Wraps the ADR-115 HA-DISCO + HA-MIND MQTT publisher as a Seed-installable +artifact with: + +- mDNS auto-discovery (`_ruview-ha._tcp`) +- Ed25519-signed witness chain for tamper-evident audit logs +- Privacy-mode flag (only semantic primitives, no biometrics) +- One-flag deferral to v0.7 for the embedded broker / v0.8 for the Matter Bridge + +## Layout + +| File | Purpose | +|---|---| +| `manifest.template.json` | Build-time manifest with `{{VERSION}}` / `{{ARCH}}` slots; `make manifest` substitutes them | +| `Makefile` | `build` / `sign` / `upload` / `release` / `verify` / `clean` targets | +| `dist/` | Created by `make build`; gitignored, holds release binaries + sha256 + sig | + +## Local build (dry-run) + +```sh +cd v2/crates/cog-ha-matter/cog +make build # builds aarch64 + x86_64 release binaries +make sign # writes .sha256 + (TODO) .sig sidecars +make manifest # prints the manifest the Seed would record +``` + +`make sign` is currently a no-op for the signature itself — the +`COGNITUM_OWNER_SIGNING_KEY` provisioning is the same TODO that +blocks [`cog-pose-estimation`](../../cog-pose-estimation/cog/Makefile). +Until then, dev cogs ship unsigned and `app-registry.json` lists +them with `"binary_signature": ""`. + +## Upload (requires `gcloud auth`) + +```sh +gcloud auth login +make upload # gsutil cp dist/* gs://cognitum-apps/cogs/{arch}/ +``` + +The GCS bucket is shared with `cog-pose-estimation` and is part of +the `cognitum-apps` project. Write access requires membership in the +`cog-publishers` IAM group. + +## app-registry.json + +Lives in the [`cognitum-one`](https://github.com/ruvnet/cognitum-one) +repo, **not here**. After `make upload` succeeds, file a PR there +that appends: + +```json +{ + "id": "ha-matter", + "version": "", + "binary_url": "https://storage.googleapis.com/cognitum-apps/cogs/{arch}/cog-ha-matter-{arch}", + "binary_sha256": "", + "binary_signature": "", + "description": "Home Assistant + Matter Cognitum Seed cog (mDNS + witness chain)", + "min_seed_version": "0.6.0", + "installable_on": ["arm", "x86_64"] +} +``` diff --git a/v2/crates/cog-ha-matter/cog/manifest.template.json b/v2/crates/cog-ha-matter/cog/manifest.template.json new file mode 100644 index 00000000..aa3e8bd2 --- /dev/null +++ b/v2/crates/cog-ha-matter/cog/manifest.template.json @@ -0,0 +1,10 @@ +{ + "id": "ha-matter", + "version": "{{VERSION}}", + "binary_url": "https://storage.googleapis.com/cognitum-apps/cogs/{{ARCH}}/cog-ha-matter-{{ARCH}}", + "binary_bytes": 0, + "binary_sha256": "", + "binary_signature": "", + "installed_at": 0, + "status": "installed" +}