Handoff: ship 0.2.0:58 agent-payment-connect; document the connect gate
Current state rewritten to :58-shipped (both onboarding stages completed-clean, validated separately); payments guide gains the scoped (agent) BTCPay connect sandbox-gate section (two-gate fail-closed design, migration 0025, GET-callback status gotcha, regtest validation facts); guide index flags it for the connect gate + migrations 0024-0025.
This commit is contained in:
@@ -19,7 +19,7 @@ its guide** — see the index below.
|
||||
## 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 editing payment / provider / merchant-profile code, the scoped-connect gate, or migrations 0020–0022 + 0024–0025, 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`.
|
||||
@@ -109,59 +109,40 @@ Operator-specific memories at `~/.claude/projects/-Users-macpro-Projects-keysat/
|
||||
policy entitlements (admin UI), then re-issue the master self-license so it takes
|
||||
effect.
|
||||
|
||||
## Current state (2026-06-16)
|
||||
## Current state (2026-06-17)
|
||||
|
||||
- **Live (registry/canonical)**: `registry.keysat.xyz` + `files.keysat.xyz/keysat.s9pk`
|
||||
publish **`0.2.0:57`** — universal multi-arch (x86_64 + aarch64), GitHub release
|
||||
`v0.2.0-57`. Migrations 0020–0023; four SDKs published; `keysat.xyz` +
|
||||
`docs.keysat.xyz` deployed.
|
||||
`:57` shipped the **`merchant-onboard`** scoped role (catalog + license self-serve, no
|
||||
master key; `src/api/api_keys.rs`) — see git log for detail.
|
||||
- **Live box `immense-voyage.local`**: `:57` was deployed this session via `make install`
|
||||
(`start-cli package install` returned clean; StartOS applies the swap async — **not
|
||||
independently confirmed**; verify the StartOS UI shows `0.2.0:57`). `publish.sh` now runs
|
||||
`make install` as step 5, so future ships auto-deploy (best-effort, non-fatal).
|
||||
- **Live / canonical**: **`0.2.0:58`** published — registry + `files.keysat.xyz/keysat.s9pk`,
|
||||
GitHub `v0.2.0-58`, universal multi-arch (x86_64 + aarch64). Live box
|
||||
`immense-voyage.local` **confirmed on `:58`** (operator-verified in the StartOS UI). All
|
||||
three public sites deployed (`keysat.xyz`, `docs.keysat.xyz`, `registry.keysat.xyz`).
|
||||
Migrations through 0025; four SDKs published.
|
||||
|
||||
- **Onboarding doc-harness — Stage 1 (no payments): `completed-clean` this session, committed + pushed.**
|
||||
`licensing-service-startos/onboarding-harness/` runs the global `onboarding-tester` agent
|
||||
docs-only against the SDK-integration journey (loop converged 5→1→0 stumbles over 3 runs).
|
||||
Doc fixes shipped to `keysat-docs` (integrate/agent/wire-format) + the served `openapi.rs`
|
||||
spec; the publishable walkthrough is harvested to `agent.html` #worked-example. The
|
||||
`openapi.rs` fixes reach the live spec only on the **next daemon release**; keysat-docs
|
||||
deploys independently. Full detail: `onboarding-harness/STAGE1-RESULT.md`. **Stage 2 (regtest
|
||||
buyer-pays) is gated on agent-payment-connect slices 3–5 below.**
|
||||
- **Shipped in `:58` — agent-payment-connect complete (slices 1–5).** A scoped key with the
|
||||
à-la-carte `payment_providers:write` scope connects a BTCPay provider over the API, but
|
||||
ONLY on a sandbox daemon (`KEYSAT_SANDBOX_MODE`) for a non-mainnet store;
|
||||
master/mainnet/production + disconnect stay master-only. The gate fails closed: the store's
|
||||
network is resolved from its on-chain receive address at callback, anything not provably
|
||||
non-mainnet is denied. Migrations 0024–0025. Three reviewer passes; live gate
|
||||
`validate-gate.sh` 10/10. Detail: `docs/guides/payments.md`, `plans/agent-payment-connect-scope.md`.
|
||||
|
||||
- **In progress — agent-payment-connect (phase 2)**. Approved spec:
|
||||
`plans/agent-payment-connect-scope.md`. Lets a scoped key connect a BTCPay provider, but
|
||||
ONLY on a sandbox daemon and ONLY for a non-mainnet network — never folded into a role
|
||||
(a key that can repoint settlement is a fund-redirection key).
|
||||
- **Foundation committed this session (`3afac07`, origin+gitea; NOT version-bumped)** —
|
||||
slices 1–2 of 5: `Config.sandbox_mode` (env `KEYSAT_SANDBOX_MODE`, never API-settable;
|
||||
surfaced in `/v1/admin/tier`); migration 0024 `scoped_api_keys.extra_scopes`; per-key
|
||||
à-la-carte scopes (`GRANTABLE_EXTRA_SCOPES=["payment_providers:write"]`, granted via
|
||||
`extra_scopes`, in NO role — `grants()` carves it out of full-admin's wildcard;
|
||||
fail-closed parsing). Reviewer pass clean after fixing the full-admin-wildcard P1.
|
||||
- **Pending — slices 3–5**: `require_provider_connect` gate (master→any; scoped+
|
||||
`payment_providers:write`→only if `sandbox_mode` AND non-mainnet); BTCPay OAuth wiring
|
||||
(record `scoped_initiator` in `btcpay_authorize_state` at `start_connect`, network-check
|
||||
at `finish_connect`, migration 0025); Zaprite stays master-only. **The BTCPay on-chain
|
||||
address network detection MUST be validated against a live regtest box** before
|
||||
shipping (classify address prefix `bc1`/`tb1`/`bcrt1`, fail-closed to mainnet; the
|
||||
payment-method id is `BTC-CHAIN` vs `BTC` by version).
|
||||
- **Onboarding doc-harness — BOTH stages `completed-clean`.** Stage 1 (SDK integration, no
|
||||
payments) prior session; **Stage 2 (regtest buyer-pays) this session, converged run 1→3.**
|
||||
Rig + publishable walkthrough: `onboarding-harness/stage2/STAGE2-RESULT.md`. Doc fixes live
|
||||
on `keysat-docs` (agent.html/install.html); the served `openapi.rs` BTCPay paths reach the
|
||||
live spec as of `:58`. The two stages have only been validated **separately**, not as one run.
|
||||
|
||||
- **Work queue (next, in order)**:
|
||||
1. Build gate slices 3–5 (above) — validate the BTCPay address fetch on regtest.
|
||||
2. Confirm `:57` is live on `immense-voyage.local` (StartOS UI).
|
||||
3. Operator data action (master key): grant `unlimited_merchant_profiles` to Pro/Patron.
|
||||
4. 3 multi-profile UIs + split `audit:read` (ROADMAP / Open TODOs).
|
||||
- **Next (priority order)**:
|
||||
1. Operator data action (needs the master key): grant `unlimited_merchant_profiles` to
|
||||
Pro/Patron on the live master (confirmed-absent details in Open TODOs).
|
||||
2. 3 multi-profile UIs + split `audit:read` (ROADMAP / Open TODOs).
|
||||
3. Optional: a single combined SDK-integration + buyer-pays onboarding-tester run.
|
||||
|
||||
- **P2/P3 debt (unchanged)**: `set_product_entitlements_catalog` missing `rows_affected`
|
||||
guard; no rate-limit on purchase/redeem (spoofable XFF); `422`/`415` plain-text not JSON;
|
||||
`slug` unvalidated; `GET /v1/admin/products` 405 vs OpenAPI; dep advisories (`sqlx`→≥0.8.1,
|
||||
`rustls-webpki`→≥0.103.12); no CI / fmt-clippy unenforced; field-naming drift; outbound
|
||||
webhook SSRF; design-contract conformance (see ROADMAP).
|
||||
- **P2/P3 debt (unchanged, see ROADMAP)**: `set_product_entitlements_catalog` missing
|
||||
`rows_affected` guard; no rate-limit on purchase/redeem (spoofable XFF); `422`/`415`
|
||||
plain-text not JSON; `slug` unvalidated; dep advisories (`sqlx`→≥0.8.1,
|
||||
`rustls-webpki`→≥0.103.12); no CI / fmt-clippy unenforced; outbound webhook SSRF;
|
||||
design-contract conformance.
|
||||
|
||||
- **Tests/build**: `cargo check` + `npm run check` clean (1 intentional deprecation
|
||||
warning); full suite green — lib unit **13**, api **59**, subscriptions 7, upgrades 9,
|
||||
worker 3, crosscheck 4, migrations 9 (through 0024). No new clippy warnings. FK
|
||||
enforcement confirmed — sqlx pool sets `foreign_keys(true)` per connection.
|
||||
- **Tests/build**: full suite green — lib **18**, api **65**, subscriptions 7, upgrades 9,
|
||||
worker 3, crosscheck 4, migrations 9 (through **0025**); `cargo check` + `npm run check`
|
||||
clean (1 intentional deprecation warning); new code clippy-clean.
|
||||
|
||||
Reference in New Issue
Block a user