Record registry-submission process + start-cli/prepare.sh; capture eval P2 backlog

Refresh AGENTS Current state for the full-eval session; document the email-based
community-registry submission flow and the start-cli installer in the packaging
guide; add a ROADMAP Security & hardening section so the eval P2s survive
EVALUATION.md overwrites.
This commit is contained in:
Keysat
2026-06-18 17:22:58 -05:00
parent 178e4677a4
commit 255d669cf0
3 changed files with 69 additions and 23 deletions
+21 -17
View File
@@ -95,9 +95,11 @@ Operator-specific memories at `~/.claude/projects/-Users-macpro-Projects-keysat/
- `riscv` build target is unverified and not declared in the manifest; the wrapper `Makefile`
now pins `ARCHES` to `x86 arm` so no target (even a bare `make`) attempts it. Revisit only if
a riscv StartOS target appears.
- StartOS Community Registry submission — remaining gap is a `prepare.sh` for the clean-Debian
first build (plus the on-box manual verification); functional criteria otherwise pass. Detail
in ROADMAP. Submission criteria themselves still unpublished; reach out when ready.
- StartOS Community Registry submission — `prepare.sh` shipped (2026-06-18). Submission is
**email-based** (no PR, no form): mail `submissions@start9labs.com` a link to the public wrapper
repo; Start9 builds-from-source on a clean box → Community Beta → production-on-reply. Resolve two
unknowns with Start9 *before* submitting: (1) source-available `LicenseRef-Keysat-1.0` acceptability,
(2) whether the 0.4.x build still invokes `prepare.sh`. On-box manual verification still pending. Detail in ROADMAP.
- Split `audit:read` out of the blanket `:read` scope into its own tier so a
Read-only scoped key can read dashboards/licenses but NOT the full audit log
(`api/api_keys.rs::Role::grants`). Deferred from the scoped-keys session.
@@ -110,17 +112,19 @@ Operator-specific memories at `~/.claude/projects/-Users-macpro-Projects-keysat/
public sites (keysat.xyz, docs.keysat.xyz) live. All repos synced to **both** GitHub + gitea.
`keysat-registry-landing` remotes deleted by the operator.
- **Shipped `:60` — Zaprite auto-charge silent-lapse fix.** `try_auto_charge_zaprite` suppresses manual-pay
only for a settled status (`PAID`/`COMPLETE`/`OVERPAID`, via the new `zaprite_charge_settled` helper + unit
test); any other/unknown status falls through to the manual-pay pay link. Allowlist by design. No schema/SDK change.
- **Decided — Keysat sends no buyer email.** Buyer email + the per-profile SMTP send path are dropped
(`plans/keysat-smtp-emails.md` superseded; dormant `merchant_profiles.smtp_*` flagged in code). The surviving
kernel, operator failure alerts, is reframed onto StartOS notifications/health (ROADMAP "Operability & alerts").
- **Docs reconciled:** false "Keysat emails the license" claim removed from docs.keysat.xyz; `HOW_IT_WORKS.md`
corrected (subscriptions + merchant profiles shipped, no email); new design-checker-clean Merchant profiles
docs section. `unlimited_merchant_profiles` confirmed live on Pro + Patron policies (Creator excluded).
- **Next (priority):** 1) automated multi-profile webhook routing test (ROADMAP, Effort S). 2) split `audit:read`
from the blanket `:read` scope. 3) operator-alerts-via-StartOS (verify the start-sdk 1.3.2 API first).
4) registry-submission `prepare.sh` + on-box verification.
- **Tests/build:** `cargo check` + wrapper `tsc` clean; `zaprite_charge_settled` unit test green; full suite
through 0025 last green. Pre-existing docs.css radius drift (10px vs 12px `r-lg`, 3 spots) noted; not blocking.
- **This session — full eval + three P1 fixes (all committed & pushed).** Ran the five-agent `/full-eval`
(evaluator, security-auditor, exerciser, doc-auditor, start9-spec-checker); report in `EVALUATION.md`
(no P0s; strong crypto/auth/webhook posture). Fixed all three P1s: (1) crosscheck harness `run_ts.mjs`
hardcoded `/sessions/...` path → resolves relative to repo (keysat-root); (2) Rust SDK + `keysat-docs`
imported `licensing_client` not `keysat_licensing_client` — fixed, plus two latent bugs it masked (example's
undeclared `anyhow` → stdlib; doctest `include_str!` of a missing file → inline PEM); (3) added
`licensing-service-startos/prepare.sh` clean-Debian build bootstrap. Reviewer-approved; verified green.
- **Registry submission mechanism researched.** Email-based (no PR/form) — see Open TODOs + ROADMAP. Two
blocking unknowns to clear with Start9 first: license acceptability + whether 0.4.x still uses `prepare.sh`.
- **Prior context still current:** `:60` Zaprite silent-lapse fix shipped; Keysat sends no buyer email
(SMTP path dormant); docs reconciled; `unlimited_merchant_profiles` live on Pro+Patron (not Creator).
- **Next (priority):** 1) email Start9 re: license + 0.4.x build flow (gates the whole submission). 2) eval
P2 hardening — XFF rate-limit bypass, dep-advisory bumps, admin/public port split (ROADMAP "Security &
hardening"). 3) automated multi-profile webhook routing test (Effort S). 4) split `audit:read` scope.
- **Tests/build:** daemon `cargo test` ~117131 green across 8 suites; wrapper `tsc` clean; Rust SDK
`cargo build --examples` + doctest now green; crosscheck harness passes end-to-end. No CI enforces any of it.
+36 -6
View File
@@ -28,12 +28,18 @@ Longer-term backlog. Near-term state lives in `AGENTS.md` → Current state.
## Packaging & distribution
- Start9 Community Registry submission — a 2026-06-17 spec check found the wrapper passes the functional
criteria (manifest, interfaces, health check, backup/restore, BTCPay dep, actions). Remaining gap before
submission: add a `prepare.sh` to set up a clean Debian box for the first build (copy the one from
`hello-world-startos`), then run the on-box manual verification (install / backup / restore / logs).
Submission criteria themselves remain unpublished; reach out to Start9 when ready. (Icon-render and the
source-available license are intentionally not treated as blockers.)
- **Start9 Community Registry submission.** Mechanism (researched 2026-06-18): **email-based, not a PR or
form.** Mail `submissions@start9labs.com` (the 0.3.5.x docs say `submissions@start9.com` — addresses are
inconsistent) a link to the public wrapper repo (+ detailed README); both wrapper and upstream source must
be public. Start9 snapshots the repo, **builds from source on a clean Debian box** (`prepare.sh` + `make`; a
failed first build bounces the submission), installs + tests on real hardware (metadata, install/uninstall,
interfaces, health, backup/restore, low-resource device), lands it in Community **Beta**, and promotes to
production when you reply asking. Updates follow the same loop. `start-cli s9pk publish` is **self-hosted-registry
only** — unrelated to community intake. `prepare.sh` shipped this session (`licensing-service-startos/prepare.sh`).
**Clear with Start9 before submitting:** (1) is the custom source-available `LicenseRef-Keysat-1.0` acceptable
(docs conflict: "source available" vs "Open Source License") — highest-leverage; a hard No blocks regardless of
build-readiness; (2) does the 0.4.x build flow still invoke `prepare.sh` (a 0.3.5.x concept, absent from 0.4.x
docs). Then the on-box manual verification. Functional criteria otherwise pass (2026-06-17 spec check).
## Operability & alerts
@@ -53,6 +59,30 @@ Longer-term backlog. Near-term state lives in `AGENTS.md` → Current state.
The dormant `merchant_profiles.smtp_*` columns (migration 0020) are now dead weight — left in place (a removal
migration isn't worth it) and flagged in `src/merchant_profiles.rs`.
## Security & hardening (2026-06-18 full-eval P2s; EVALUATION.md has full detail but is overwritten each run, so the durable list lives here)
- **X-Forwarded-For rate-limit bypass.** Login/recover/validate buckets key off the raw first XFF value
(`api/auth.rs:137`, `api/recover.rs:65`, `api/admin.rs:63`, `api/validate.rs:95`); rotating XFF defeats the
throttle. First confirm whether the StartOS front proxy overwrites XFF (decides real-world reachability), then
derive client IP from the trusted-proxy connection with a peer-socket fallback.
- **Dependency advisories** (mechanical, low-risk): bump `sqlx 0.7.4` → ≥0.8.1 (RUSTSEC-2024-0363),
`rustls-webpki 0.101.7` → ≥0.103.13 (RUSTSEC-2026-0098/0099/0104), update start-sdk for the wrapper's
`fast-xml-parser` (GHSA-5wm8-gmm8-39j9); re-run `cargo audit` / `npm audit`.
- **Admin UI co-located with the public API** on the single `:8080` interface (`startos/interfaces.ts`) — operator
can't network-isolate admin. Split the admin SPA + `/v1/admin/*` onto their own port/interface.
- **Webhook-endpoint registration accepts `file://` / loopback URLs** (`webhooks.rs:106`, admin-gated) — add a
scheme + host allowlist (reject non-http(s), loopback, link-local).
- **Runtime-prepared SQL** in `db/repo.rs` + `subscriptions.rs` (no compile-time column check; this class already
500'd every paid purchase once on `:52`) — migrate the money-path queries to compile-checked `sqlx::query!`.
- **`rate_buckets` grows unbounded** (`rate_limit.rs:63`, one row per client IP on a public endpoint, no reaper) —
add a reaper mirroring the session/redemption reapers in `main.rs`.
- **No CI.** Stand up one job (`cargo test && cargo clippy && tsc --noEmit`, ideally `cargo fmt --check`); the suite
is good but unenforced, so green depends on the operator remembering to run it before `publish.sh`.
- Doc-drift P3 cluster (each one-liners, see EVALUATION.md): BUILDING.md Node 20→22 / Rust 1.75→1.88, broken docs
`/changelog` footer link, README "Show credentials" → "Show admin API key", PORTING_SDK stale (Python/Go shipped;
crate renamed), testing.md stale test counts, and the `unlimited_merchant_profiles` guide/code-comment ("still
needs adding") vs AGENTS ("confirmed live") contradiction — resolve with a live `GET /v1/products/keysat/policies`.
## Licensing model
- Evaluate Elastic License v2 vs the current custom `LicenseRef-Keysat-1.0` (parked decision).
+12
View File
@@ -28,6 +28,18 @@ npm run prettier # prettier --write startos (NOT enforced; see testing.md)
Auth for `make install` is the developer key at `~/.startos/developer.key.pem`
(private — never commit/share).
## Clean-box build bootstrap (`prepare.sh`)
`prepare.sh` (in `licensing-service-startos/`) installs every HOST prerequisite a
fresh Debian/Ubuntu box needs before `make`: apt prereqs (build-essential, jq, git,
squashfs-tools(-ng)), Node 22 (NodeSource), Docker (+ QEMU binfmt for cross-arch),
and **start-cli** via the official installer —
`curl -fsSL https://start9.com/start-cli/install.sh | sh` (drops the binary in
`~/.local/bin`). Rust is **not** installed on the host; the daemon compiles inside
the Dockerfile (`FROM rust:1.88`). Idempotent; apt-based only. Caveat: `prepare.sh`
is a 0.3.5.x submission convention — the 0.4.x docs never mention it, so Start9's
0.4.x build flow may not actually invoke it (confirm before relying on it).
## ALWAYS: bump the version before building
Edit `startos/versions/v0.2.0.ts` — increment `version: '0.2.0:N'` and prepend a