Skip to content

feat: TAM-6867: Canopy enrolment and status reporting channel#116

Open
dannash100 wants to merge 7 commits into
mainfrom
feature/tam-6867-seedling-x-canopy-establish-implement-the-connection-channel
Open

feat: TAM-6867: Canopy enrolment and status reporting channel#116
dannash100 wants to merge 7 commits into
mainfrom
feature/tam-6867-seedling-x-canopy-establish-implement-the-connection-channel

Conversation

@dannash100

@dannash100 dannash100 commented Jul 16, 2026

Copy link
Copy Markdown

TAM-6867. The seedling side of the Seedling x Canopy connection channel: enrolment, a periodic status push over bestool-canopy (the transport library from the card), response logging, and the operator surfaces for it.

Screenshot 2026-07-17 at 2 49 06 PM

Spec

New tracey rules, all covered and verified:

  • i[canopy.enrol], i[canopy.enrol.single], i[canopy.status], i[canopy.deregister] (interface.md) — the OI surface, plus an already_enrolled error code.
  • r[canopy.registration], r[canopy.push], r[canopy.push.response], r[canopy.push.fault] (runtime.md) — enrolment claims a pre-created Canopy server record; while enrolled, a report goes up every minute; the response is logged and retained; failures escalate log level after five consecutive misses.
  • w[routes.canopy] (web.md) — the web page.

Implementation

  • CanopyProvider (crates/core/src/runtime/canopy.rs, modelled on TailscaleProvider): decrypts the operator's enrolment ticket, mints a P-256 device key, claims the server record via the begin/complete proof-of-possession handshake (over the canopy tailnet when reachable, public mTLS otherwise), and persists the registration with bestool-canopy's machine-bound encrypted store at <data-dir>/canopy/. The push loop reports source: "seedling", version/host/uptime, and health checks for the proxy, resolver, and apps; Canopy's response is logged and surfaced on /canopy/status.
  • OI: /canopy/enrol and /canopy/deregister (async arms in server.rs), /canopy/status (sync dispatch).
  • CLI: seedling-ctl canopy enrol|status|deregister.
  • Web: /canopy page — status display, enrolment form (masked passphrase, fields cleared after submission), confirmed deregister.
  • .cargo/config.toml pins CANOPY_OPENAPI_OFFLINE=1 so builds use bestool-canopy's committed OpenAPI snapshot instead of fetching it live.

Notes

Testing

  • 7 new core tests (runtime::canopy, oi::handler::canopy) covering ticket validation, wrong-passphrase, single-registration refusal, status shape, deregistration round-trip, and the payload contract.
  • 8 new web tests (Canopy.test.tsx); full frontend suite 308/308.
  • cargo test --workspace, cargo clippy, cargo fmt, and tracey query status (all four specs at 100% coverage) clean.

@github-code-quality

github-code-quality Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript, Rust

TypeScript / code-coverage/vitest

The overall coverage in the branch is 66%. The coverage in the branch is 65%.

Show a code coverage summary of the most impacted files.
File e14aa26 bf34777 +/-
src/routes/Apps.tsx 74% 78% +4%
src/routes/Canopy.tsx 0% 91% +91%

Rust / code-coverage/rust

The overall coverage in the branch remains at 55%, unchanged from the branch.

Show a code coverage summary of the most impacted files.
File e14aa26 bf34777 +/-
crates/core/src/oi/server.rs 18% 16% -2%
crates/ctl/src/main.rs 7% 7% 0%
crates/core/src/oi/handler.rs 99% 99% 0%
crates/core/src...test_support.rs 100% 100% 0%
crates/ctl/src/canopy.rs 0% 0% 0%
crates/protocol/src/error.rs 100% 100% 0%
crates/core/src/system/stub.rs 23% 25% +2%
crates/core/src...ntime/canopy.rs 0% 29% +29%
crates/core/src...ndler/canopy.rs 0% 58% +58%

Updated July 17, 2026 00:46 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant