Files
keysat-root/AGENTS.md
T
Keysat 35ee302592 Refresh current state and document per-repo git remotes
Rewrite the Current state section after the merchant-profile bug-fix session and
record that the daemon repo's main tracks GitHub (origin) with a gitea backup,
while root + plans are Gitea-only — check remotes before pushing.
2026-06-12 20:16:24 -05:00

120 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md — Keysat workspace
Self-hosted, Bitcoin-native software licensing service running as a StartOS 0.4.x
package, with four wire-compatible SDKs and a public landing/docs site.
This file holds whole-repo, every-session facts. Subsystem detail lives in scoped
guides under `docs/guides/` (symlinked to `.claude/rules/` so Claude Code
auto-loads each when you edit matching files). **Before editing a subsystem, read
its guide** — see the index below.
## Stack
- **Daemon**: Rust 1.88, `axum`, `sqlx` + SQLite, Ed25519 signing.
- **Wrapper**: TypeScript, `@start9labs/start-sdk ^1.3.2`, `@vercel/ncc` bundle, Node 22.
- **SDKs**: TS (npm), Rust (crates.io), Python (PyPI), Go (proxy.golang.org).
- **Platform**: StartOS 0.4.0.x (LXC under the hood — commands/paths reflect that, not Docker).
- **Payment providers**: BTCPay Server (required dep); Zaprite (optional, gated by `zaprite_payments`).
## Subsystem guides (read before editing the area)
- Before editing the daemon source, read `docs/guides/daemon-architecture.md`.
- Before editing payment / provider / merchant-profile code or migrations 00200022, read `docs/guides/payments.md`.
- Before touching self-license or tier-gating code, read `docs/guides/licensing-tiers.md`.
- Before changing the LIC1 wire format, crypto, or crosscheck fixtures, read `docs/guides/crypto-wire-format.md`.
- Before building, bumping the version, or editing the StartOS wrapper, read `docs/guides/startos-packaging.md`.
- Before editing the admin SPA (`web/index.html`), read `docs/guides/admin-ui.md`.
- Before editing public site/docs copy, read `docs/guides/website-copy.md`.
- Before adding/altering tests or relying on lint/CI, read `docs/guides/testing.md`.
## Build / test / run (quick ref)
From `licensing-service-startos/`: `make x86` | `make arm` | `make universal` |
`make install` | `make clean` | `npm run check`. From
`licensing-service-startos/licensing-service/`: `cargo check` | `cargo build
--release` | `cargo test` | `cargo test --test <suite>` | `cargo test <name>`.
Details, the version-bump-before-build rule, and release scripts:
`docs/guides/startos-packaging.md`. Test suites, the no-CI / formatting-not-enforced
status, and known-failing tests: `docs/guides/testing.md`.
## Directory layout
```
licensing-service-startos/ daemon + StartOS wrapper (s9pk package source)
licensing-service/src/ Rust daemon → guides/daemon-architecture.md
licensing-service/migrations/ SQLite migrations (numbered, additive)
licensing-service/web/index.html embedded admin SPA → guides/admin-ui.md
licensing-service/tests/ integration suites → guides/testing.md
startos/ wrapper TS → guides/startos-packaging.md
Dockerfile Makefile s9pk.mk build pipeline
keysat-xyz-landing/ keysat-docs/ keysat-registry-landing/ public sites → guides/website-copy.md
licensing-client-{rust,ts,python,go}/ the four SDK source repos
activate-license-template/ Tauri desktop template for license activation
keysat-design-system/ design tokens / brand assets
plans/ design specs (multi-provider-payment-model.md, keysat-smtp-emails.md)
tests/crosscheck/ cross-language LIC1 verifier → guides/crypto-wire-format.md
```
Note: the daemon (`licensing-service-startos`, repo `keysat`), each SDK, and
`plans/` are **separate git repos** — commit code/plan changes in their own repo.
The root `Licensing` repo (`keysat-root`) tracks only `AGENTS.md` + `docs/guides/`
+ `.claude/rules/`. **Remotes differ per repo**: the daemon's `main` tracks
**GitHub** (`origin`, the public upstream) with a `gitea` backup — plain `git push`
goes to GitHub, so also `git push gitea main`; root + plans are **Gitea-only**.
Run `git remote -v` (full) and check what the branch tracks before pushing.
## Conventions (whole-repo)
- Daemon licensed `LicenseRef-Keysat-1.0` (custom, source-available); SDKs MIT.
- Commits in imperative mood, body only when the "why" isn't obvious. **Sign as
Keysat (Grant), not Claude** — git user is `Keysat`.
- Direct push to `main` + run `~/.keysat/publish.sh` is the authorized release flow
until launch.
- Never rewrite user-facing copy outside the explicit scope of a request.
## Never
- **No AI co-authorship** on commits or PRs (no "Co-Authored-By", no "Generated with…").
- **Don't push `--no-verify`** or bypass hooks unless explicitly authorized.
- **Don't commit built artifacts** (`*.s9pk`, `keysat-*.s9pk`, `javascript/`) or
**secrets** — reference env-var names; real values live in `~/.keysat/filebrowser.env`
and `/data/keysat-license.txt` outside the repo.
## Memory references
Operator-specific memories at `~/.claude/projects/-Users-macpro-Projects-licensing-Licensing/memory/`
(scan before a major change): `keysat_release_workflow.md`,
`no_unauthorized_copy_changes.md`, `keysat_admin_ui_pill_convention.md`,
`startos_lxc.md`, `startos_registry_icon_unrenderable.md`, `keysat_open_threads.md`.
## Open TODOs
- Extend `publish.sh` to build + upload aarch64 (arm builds fine; only x86 ships
today), or narrow the manifest's arch claim. `riscv` target unverified.
- StartOS Community Registry submission criteria — Start9 hasn't published the
checklist; reach out directly when ready.
- Registry icon doesn't render in the StartOS marketplace (see `guides/startos-packaging.md`).
## Current state (2026-06-12)
- **Live**: server `immense-voyage.local` runs daemon `0.2.0:52` (from `:45`;
migrations 00200022 applied). Registry `registry.keysat.xyz` still publishes
`:45`. Four SDKs published; `keysat.xyz` + `docs.keysat.xyz` deployed.
- **`:52` = multi-provider/merchant-profile model**: data model + backend
resolution shipped and audited sound; the resolution/CRUD query surface now has
test coverage. See `docs/guides/payments.md`.
- **Prod runs a known-broken `:52`**: a purchase-path ambiguous-column bug (broke
*every* paid purchase) is **fixed, committed, and pushed** (daemon `31f4670`, on
GitHub + gitea), but **no `:53` build/install yet**, so the live server is still
broken. No live buyers, so not urgent — but this is the top next step.
- **Next, in priority order**: (1) bump `:53` + `make x86` + `make install` to ship
the fix; (2) resolve the 3 red tests — delete the dead `payment_provider_preference_round_trip`,
decide the mock-injection seam for the two `paid_purchase_*` (see `docs/guides/testing.md`);
(3) build the 4 deferred UIs + add `unlimited_merchant_profiles` to master
Pro/Patron policies; (4) re-register the master Zaprite webhook; (5) optional:
run formatters as a standalone commit.
- **Tests/build**: `cargo check` clean (1 intentional deprecation warning); api
43 pass / 3 known-fail (test-debt), other suites green. No CI; fmt/prettier not
enforced or clean. Latent: confirm the sqlx pool sets `PRAGMA foreign_keys = ON`
per-connection (else FKs aren't runtime-enforced) — flagged by review, unchecked.