f574f025a6
Trim AGENTS.md to whole-repo, every-session facts (154 -> 110 lines) and move subsystem guidance into docs/guides/*.md, each with paths: frontmatter and a one-line index entry in AGENTS.md. Symlink each guide from .claude/rules/ so Claude Code lazy-loads it by matching path; track those symlinks via a .gitignore exception (.claude/settings.local.json stays ignored).
111 lines
6.1 KiB
Markdown
111 lines
6.1 KiB
Markdown
# 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 0020–0022, 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: `licensing-service-startos/` and each SDK are **separate git repos**; the
|
||
root `Licensing` repo is a workspace backup that tracks docs (AGENTS.md, plans,
|
||
guides) but not the code. Commit code changes in their own repo.
|
||
|
||
## 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**: operator's server `immense-voyage.local` runs daemon `0.2.0:52`
|
||
(installed from `:45`; migrations 0020–0022 applied). Registry
|
||
`registry.keysat.xyz` still publishes `:45` — `:52` built/installed but **not
|
||
published**. Four SDKs published; `keysat.xyz` + `docs.keysat.xyz` deployed.
|
||
- **`:52` = multi-provider/merchant-profile model**: data model + backend
|
||
resolution shipped and audited sound. **Deferred (parked):** four UIs (buy-page
|
||
rail picker, product-edit profile picker, per-profile SMTP form, rail-preference
|
||
editor) and the `unlimited_merchant_profiles` master-policy entitlement. See
|
||
`docs/guides/payments.md`.
|
||
- **Open bug fix not yet shipped**: a purchase-path SQL bug (ambiguous column,
|
||
broke every paid purchase on `:52`) is **fixed in the working tree but
|
||
uncommitted**, so prod `:52` is still broken until a `:53` rebuild+reinstall. No
|
||
live buyers yet, so not urgent. Working tree also has the test compile-fixes, a
|
||
new query-audit test, the manifest license fix, and an unused-import removal —
|
||
all uncommitted. See `docs/guides/payments.md` and `docs/guides/testing.md`.
|