Commit Graph

24 Commits

Author SHA1 Message Date
Grant 4b9ef0ea8c v0.2.0:8 release notes + integration doc section 8 update
Notes cover the entitlements catalog feature shipped in 68dfe7f
plus the four SDK 0.3.0 cuts (TS / Rust / Python / Go) that
surface the catalog on listPublicPolicies. Phase 2 (side-by-side
card-grid policy authoring UI) is queued for v0.2.0:9.

KEYSAT_INTEGRATION.md section 8 grows a subsection explaining the
catalog mechanics: bubble picker, buy page rendering, SDK surface,
catalog-stability rule.

Test count: 78 (unchanged from :7 except for migration_0014 already
counted in the prior commit).
2026-05-10 08:01:43 -05:00
Grant b95b47e0d5 v0.2.0:7 — align package copy with website positioning
The Start9 registry card was still showing "Keysat — self-hosted
Bitcoin-paid software license server" while keysat.xyz now leads
with "Bitcoin-native self-hosted licensing service for software
creators." Operators landing on the registry from the marketing
site got a jarring tagline mismatch.

Aligned everywhere the old copy was hardcoded:

- startos/manifest/i18n.ts (short + long descriptions — these
  drive the registry card)
- assets/ABOUT.md (in-StartOS About panel)
- README.md (root + licensing-service/)
- licensing-service/Cargo.toml description

Long description also picked up two updates that should have
landed when the features did but never made it into the marketing
copy:
- Zaprite mention (Bitcoin + cards) alongside BTCPay
- Recurring subscriptions + in-place tier upgrades

Pure copy change. No code, no behavior, no schema. Republishing as
:7 because the registry card text lives inside the .s9pk and
won't refresh on operators' boxes without a version bump.
2026-05-09 19:10:26 -05:00
Grant ff92ed0463 v0.2.0:6 release notes — recurring + trials + self-tier live refresh
Big release notes pass covering the testing-driven fixes from
2fbd36f (P0 batch), 54f7ea0 (P1 bundle), 927ac2b (UX polish),
89d505b (integration doc).

Test count callout: 77 (unchanged from :5).
2026-05-09 14:04:36 -05:00
Grant 58939d1dc6 v0.2.0:5 release notes — tier upgrades functional end-to-end
Bumps the milestone version + writes the operator-facing release
notes covering the complete tier-upgrades feature delivered across
8ce78ab (Phase 1 schema), f8affdb (Phase 2 quote/apply), b7fa6c7
(Phase 3 buyer endpoints + webhook), c5d716a (Phase 4 admin
endpoint + renewal-worker hook), and fb062d5 (Phase 5 admin UI).

Test count callout: 77 (was 57 at v0.2.0:4).
2026-05-08 20:16:14 -05:00
Grant 6112618c1b v0.2.0:4 release notes — recurring subscriptions functional end-to-end
Bumps the milestone version + writes the operator-facing release
notes covering the complete recurring-subs feature delivered across
7007bf8 (Phase 2 worker), c301eac (Phase 4 admin UI + buy page),
5d7f68f (Phase 6 cancellation backend), and 4bdc506 (Phase 6 cancel
UI).

Test count callout: 57 (was 42).
2026-05-08 18:04:51 -05:00
Grant 667db6ffd4 v0.2.0:3 release notes — durable provider switching
Bump with notes covering the active_payment_provider preference,
the new Activate <provider> actions, and the symmetric Disconnect
handling.

Test count: 42.
2026-05-08 16:51:47 -05:00
Grant 0a76c9d121 v0.2.0:2 release notes — Zaprite + recurring subs schema
Bump to v0.2.0:2 with notes covering Zaprite as second payment
provider, migration 0011 (recurring subs schema dormant), 0012
(zaprite_config). Test count 41.
2026-05-08 16:35:40 -05:00
Grant 622fa77e29 v0.2.0:1 — drop FOUNDERS50 placeholder from buy-page discount input
Per operator feedback: the discount-code field on /buy/<slug> was
showing 'FOUNDERS50' as a placeholder, which confused buyers (some
tried it as a real code, some assumed Keysat shipped a default
discount). Empty placeholder now; buyers paste their actual code.

No semantic change. Wrapper-only revision; daemon binary unchanged
beyond the embedded HTML template.
2026-05-08 13:41:17 -05:00
Grant b45e84c3a2 v0.2.0:0 cutover — first non-alpha milestone
Swaps the version graph's current pointer from v0_1_0 to v0_2_0.
v0.1.0 stays in `other` so operators on the alpha line can upgrade
through the StartOS marketplace.

Per CUTTING_V0.2.0.md the steps are:
  1. swap versions/index.ts (this commit)
  2. npm run check (passed)
  3. make x86 (next)
  4. publish.sh (next)

What v0.2.0:0 represents — see the release notes in
startos/versions/v0.2.0.ts. Headlines: web admin SPA replaces
Actions for day-to-day work; multi-currency pricing functional
end-to-end; buyer self-service recovery; opt-in community
analytics; webhook delivery DLQ visible in dashboard;
PaymentProvider trait abstraction makes Zaprite drop-in for v0.3;
five-language SDK parity (daemon + Rust + TS + Python + Go).
2026-05-08 13:28:46 -05:00
Grant aeaab2d861 v0.1.0:51 — multi-currency complete + analytics UX polish
Bump with notes covering the SPA polish batch + edit-product currency
support. Last polish pass before v0.2.0:0 cutover.

Test count unchanged at 38. Straight drop-in upgrade from :50.
2026-05-08 13:23:00 -05:00
Grant ec75919d72 v0.1.0:50 release notes — hotfix for migration checksum crash-loop
Drop-in upgrade for operators stuck on :49 crash-loop. No data loss.
2026-05-08 13:00:35 -05:00
Grant 29be2405a8 v0.1.0:49 — multi-currency pricing functional end-to-end
Bump version with release notes covering Phases 2-6 of the multi-
currency design (admin UI write path, buy page fiat rendering, rate
fetcher, invoice rate recording, currency-aware discount codes).
Operators can list products in USD/EUR and accept BTC; the daemon
converts at invoice creation and pins the rate.

Test count: 37. Straight drop-in upgrade from :48.
2026-05-08 12:22:14 -05:00
Grant 201c081009 v0.1.0:48 — multi-currency schema foundation
Bump version with release notes for migration 0010 (additive multi-
currency columns + backfill) and the model/repo updates wiring
the new fields into the read/write paths.

Test count: 33. Straight drop-in upgrade — no admin action,
backfill runs automatically in the migration transaction.
2026-05-08 12:01:01 -05:00
Grant 7ce30008ff v0.1.0:47 — opt-in community analytics + v0.2.0:0 plumbing parked
Bumps version with release notes covering:
- Community analytics opt-in (admin Overview surface, off by default,
  full privacy disclosure including a live preview of the exact
  JSON heartbeat that would be sent)
- Floor-to-5 anti-fingerprinting on counts pinned by test
- Draft v0.2.0:0 release notes parked at startos/versions/v0.2.0.ts
- CUTTING_V0.2.0.md cutover guide

Test count: 32. Straight drop-in upgrade from :46.
2026-05-08 11:42:28 -05:00
Grant 02f80b04eb v0.2.0:0 plumbing prep — draft version file + cutover doc
Adds startos/versions/v0.2.0.ts as a draft milestone version entry,
ready to swap in as `current` when we're ready to cut. NOT yet wired
into the version graph at versions/index.ts — flipping that switch
is a release decision (one-line change there, then make x86 +
publish), and the draft sits parked so we can iterate on the
release-notes content without committing to the cut.

Format note: the SDK's VersionInfo.of() expects releaseNotes as a
LocaleString (Record<string, string>), not the string[] form
v0.1.0.ts uses. The new file uses the modern shape; v0.1.0.ts keeps
its existing form to avoid churn on the alpha line.

CUTTING_V0.2.0.md walks the operator (or future me) through the
4-step cutover: edit versions/index.ts to swap in v0_2_0, npm run
check, make x86, publish. Plus rollback notes if anything goes
sideways post-cut.

Why park rather than cut now:
1. The user said "prepare for the version 0.2 plumbing" — that's
   "prepare" not "do". The cutover is intentional in the user's
   workflow, not bundled into a routine push.
2. Cutover changes how the StartOS marketplace renders the upgrade
   dialog to existing :N installs; best to QA the release-notes
   content first.
3. SDK migration-API behavior on the upstream version bump is
   worth verifying on a test install before flipping for everyone.

The v0.2.0 release notes themselves are written conservatively —
they describe what's already shipped and stable in the alpha line
through :47, not aspirational v0.3 features.
2026-05-08 11:41:55 -05:00
Grant 763a44bbdd v0.1.0:46 — idempotent Connect BTCPay, Go SDK now part of toolchain
Closes the last T1 BTCPay UX gap from V0.2_PLAN. Connect now checks
/v1/admin/btcpay/status first; if a connection exists, returns a
clear "already connected" guidance message pointing the operator at
Disconnect → Connect for re-authorize cases. Without this guard,
re-clicking Connect spawned a new webhook subscription on BTCPay's
side every time, leaving orphan webhooks BTCPay would keep trying
to deliver to.

The Go SDK has been written and verified — all 4 crosscheck tests
pass against the shared tests/crosscheck/vector.json (the same file
the Rust/TS/Python SDKs and the daemon test against). Pure stdlib,
zero third-party dependencies. Hosted in its own repo at
github.com/keysat-xyz/keysat-client-go (private during alpha).

This release IS the 5th-language milestone: daemon + Rust + TS +
Python + Go all agree byte-for-byte on the LIC1 wire format.

Daemon binary unchanged — wrapper-only revision.
2026-05-08 11:20:17 -05:00
Grant 9c5be85c55 v0.1.0:45 — buyer self-service recovery + db-info endpoint
Bump version with release notes covering the two operator-facing
additions in f6ba1c1:
- POST /v1/recover (+ GET /recover HTML form) for buyer self-service
- GET /v1/admin/db-info for db health snapshot

Test count: 31 (was 30). Straight drop-in upgrade from :44.
2026-05-08 11:06:16 -05:00
Grant a7ea47fd63 v0.1.0:44 — DLQ in dashboard, trait migration completes, worker + crosscheck tests
Bumps version with release notes covering everything since :43:
- Webhook DLQ visible in admin SPA with one-click retry
- reconcile.rs + tipping.rs migrated onto PaymentProvider trait
  (production refactor; daemon's non-test code now contains zero
   calls to the BTCPay-specific compat accessors)
- 3 worker integration tests pin the retry/dead-letter behavior
  empirically against real HTTP receivers
- 4 daemon-side crosscheck tests pin the wire-format parser
  against the same vector.json the SDKs use independently

Test count: 30 (was 23). Straight drop-in upgrade from :43.
2026-05-08 10:44:46 -05:00
Grant 96490bf3bf v0.1.0:43 — webhook DLQ, purchase trait migration, three more tests
Bumps version with release notes covering everything since v0.1.0:42:
- Webhook DLQ: list + retry admin endpoints (operator-visible)
- Purchase migrated onto PaymentProvider trait (internal refactor)
- Tier-cap test, paid-purchase test, DLQ test
- Test count 20 → 23

Straight drop-in upgrade from :42. No migrations, no schema changes.
2026-05-08 09:39:43 -05:00
Grant c11764898b v0.1.0:42 — webhook idempotency test + free-purchase test
Two new API integration tests, both targeting production-correctness
invariants worth locking down:

- free_purchase_issues_license_inline: exercises the price=0 shortcut
  (price_sats_override=0 on a "free" tier policy). Verifies the daemon
  synthesizes a settled invoice locally, issues a license inline, and
  the inlined license_key validates round-trip via /v1/validate.

- webhook_settles_invoice_and_issues_license_idempotently: the most
  important new test in this set. A pending invoice + an InvoiceSettled
  webhook → license issued, status flipped. Re-delivering the SAME
  webhook (which providers DO retry, sometimes aggressively) must NOT
  duplicate the license. A duplicated license here means duplicated
  revenue and duplicated revocation surface area — both bad. This test
  pins the invariant.

MockPaymentProvider added to tests/api.rs: a test-only PaymentProvider
impl that bypasses HMAC verification and parses test-supplied JSON
bodies into ProviderWebhookEvent variants. Lets us drive deterministic
settle/expire/invalid events without a real BTCPay roundtrip. Never
compiled into the production binary.

Paid-purchase test deferred: purchase::start still uses the legacy
state.btcpay_client() compat accessor that downcasts to the concrete
BtcpayProvider, which the mock can't satisfy. Documented inline. Slots
in trivially after the trait migration on the v0.3 backlog.

Version bump to v0.1.0:42 with release notes covering everything since
:41 was published: lib.rs library refactor, the original 5 API tests
from 81066df, the 2 new ones above, KEYSAT_INTEGRATION.md restoration.
No daemon-behaviour changes for operators; straight drop-in upgrade
from :41.

Test count: 20 (9 unit + 4 migration + 7 API), up from 13 in :41.
2026-05-08 09:24:57 -05:00
Grant 116ed0d1f8 v0.1.0:41 — second hotfix to migration 0009; migration regression tests
The v0.1.0:40 migration was correct on clean installs but crashed at
COMMIT on any database with rows in discount_redemptions: SQLite's
deferred FK check saw the dropped parent's bookkeeping as unsatisfied
even after the rename. Fix is to rebuild discount_redemptions in the
same transaction (stash → drop → rebuild → restore) plus orphan
cleanup. Migration is idempotent; operators on :40 with a checksum
mismatch recover by deleting the version=9 row from _sqlx_migrations
and restarting.

Lands the missing migration test scaffolding too. The four tests in
licensing-service/tests/migrations.rs apply migrations against a
realistic populated database (products, policies, invoices, licenses,
machines, discount codes, redemptions, webhooks, tip attempts). The
regression test fails with the exact 787 error against the v40
migration — would have caught the bug pre-release.

KEYSAT_INTEGRATION.md is removed from this repo; it now lives in the
parent licensing/ folder.
2026-05-08 08:05:19 -05:00
Grant beedd07f07 v0.1.0:25–40 — tier model, edit forms, force-delete, license counts, migration 0009 (and hotfix); KEYSAT_INTEGRATION.md merged with downstream-LLM revisions 2026-05-07 23:35:22 -05:00
Grant 6ac118ae70 v0.1.0:24 — Keysat licensing service end-to-end
Daemon, StartOS wrapper, admin SPA, public buy/thank-you pages,
discount codes, free-license redemption, Apply-discount UX,
self-licensing, and v0.1.0 release notes.
2026-05-07 10:33:39 -05:00
MacPro 432250bffc initial 2026-04-22 17:46:43 -05:00