README.md (6619B)
1 # HarvestCircle 2 3 HarvestCircle is an open-source Nostr application for coordinating local-food 4 buying circles. 5 6 The project is in early desktop development. It is not ready for real 7 commercial use. 8 9 ## Current foundation 10 11 - Kotlin Multiplatform shared application code; 12 - Compose Desktop host; 13 - product-specific Rust core through UniFFI; 14 - local Nostr identity creation and import; 15 - operating-system keyring custody; 16 - canonical service-instance persistence through the governed SQLx host; 17 - configurable Nostr relay bootstrap; 18 - compatibility-gated native startup; 19 - reproducible source and development qualification. 20 21 ## Sovereign direction 22 23 The MVP is designed to work without a managed HarvestCircle account or API. 24 25 Future work adds canonical Radroots collective-market contracts, private buyer 26 commitments, a selectable open reference authority, pickup, and proof. 27 28 ## Build 29 30 Prerequisites include JDK 21, Rust 1.97.1, and platform packaging tools. 31 32 ```sh 33 make doctor 34 make check 35 make build 36 make governed-development-check 37 ``` 38 39 These commands always use the standalone contributor lane. Use 40 `make governed-check` or `make governed-integration-check` when a narrower 41 extbuild-governed lane is required. The full active development milestone uses 42 `make governed-development-check` on macOS aarch64 and 43 `make governed-linux-x86_64-development-check` for Linux x86_64. It verifies 44 source, runtime, generated bindings, the public storage API, the exact Radroots 45 source lock, the single SQLx-selected SQLite linkage, and offline license/source 46 policy. Network advisory services, package assembly, release evidence, signing, 47 notarization, Nix, and OCI qualification remain deferred and unclaimed until a 48 release candidate is declared with fresh authority. 49 50 ## Development branch 51 52 Active implementation proceeds on `master`. 53 54 ## Local state 55 56 HarvestCircle derives one canonical `harvestcircle`/`desktop` runtime context 57 and stores application state only in its governed `state.sqlite` service 58 database. SQLx is the sole high-level SQLite library, while 59 `radroots_service_sqlite` owns connection, authority, migration, integrity, 60 close, backup, and restore mechanics. The historical `harvestcircle.sqlite3` 61 file is legacy evidence only and is never imported, repaired, deleted, or 62 treated as current state. 63 64 The platform or development harness must supply the existing canonical state 65 root. HarvestCircle then uses the runtime context's sealed provisioning plan to 66 create or validate only `services/harvestcircle/desktop`. The SQLite host makes 67 the create-versus-existing decision atomically and returns the actual verified 68 metadata; product storage never probes the database path, recursively creates 69 roots, repairs existing permissions, or opens a raw SQLx connection. 70 71 Online backup capture returns the canonical manifest in memory and writes only 72 the governed `state.sqlite` member into a caller-selected new directory. 73 Restore accepts only a digest-bound, identity-bound, size-bounded verified 74 backup capability, closes the live host, uses the governed marker protocol, 75 and reopens recovered state before returning. There is no arbitrary database 76 repair or pathname-only restore authority. 77 78 Relay endpoints are explicit inputs validated by the pinned Radroots Nostr 79 transport policy before any socket work. HarvestCircle owns profile selection 80 and signature-verified kind-0 interpretation, while the shared transport owns 81 relay URL, destination, DNS, connection, and bounded-fetch behavior. The 82 native FFI host owns one runtime per application core and closes it 83 idempotently. Cancelling a close never reopens command admission, and a later 84 close call resumes the same shutdown. Operating-system keyring calls run 85 through an object-safe asynchronous application port and a bounded supervised 86 worker rather than directly on an async runtime worker. Callers await one-shot 87 responses; the dedicated operating-system thread alone drives the blocking 88 platform adapter. Its request queue is fixed at eight entries and credential 89 mutations carry the caller's canonical UUIDv7 durable request identity. Work 90 cancelled while still queued has no credential effect; caller loss after work 91 starts is an unknown outcome reconciled from the durable operation journal. 92 Shutdown has a fixed 30-second wait and reports success only after the worker 93 thread is joined; a timeout remains recovery-required and a later close resumes 94 the same drain. 95 96 Credential creation is native and atomic: macOS uses create-only Keychain 97 insertion, while Linux uses Secret Service creation with replacement disabled. 98 The stored zeroizing envelope binds the creating durable operation to the 99 secret. Exact same-operation replay is idempotent only when the complete 100 envelope matches; another operation conflicts and never overwrites the existing 101 credential. No compatibility path reads the former plaintext credential shape. 102 103 The state database initializes at schema v1 and applies the pinned schema-v2 104 operation-journal and schema-v3 public evidence migrations before host exposure. 105 Terminal receipts carry an explicit completion time and remain replayable for 106 exactly seven days. 107 Admission caps unfinished operations at 1,024 and all journal rows at 4,096, 108 deletes at most 256 expired terminal receipts in one transaction, reserves each 109 accepted operation's terminal row in place, and never evicts an in-window 110 receipt. The migrations, resulting tables and guards, and all three schema 111 snapshots are checksum-pinned. Invalid legacy state is refused without replacement; 112 failed migration transactions roll back atomically. 113 114 Public listing versions retain their exact signed wire, full unsigned event 115 timestamps, tolerant admission result, and first named provenance without 116 installing an account or local signer. Loads re-verify bounded original wire. 117 One durable public payload meter admits at most 4,096 versions and 120 MiB of 118 ordinary logical payload within a 128 MiB total, preserving an 8 MiB recovery 119 reserve. Exact-ID duplicates consume no additional capacity; no automatic 120 eviction or recovery bypass is exposed. 121 122 ## Project documentation 123 124 The consuming Radroots monorepo owns normative HarvestCircle specifications, 125 decisions, handoffs, reviews, and qualification evidence under 126 `docs/oss/harvestcircle/`. This standalone source tree remains independently 127 buildable and testable without that documentation tree. 128 129 ## Security 130 131 Do not submit secret keys, nsec values, signer secrets, or decrypted private 132 contracts in issues or logs. 133 134 See `SECURITY.md`. 135 136 ## Licence 137 138 HarvestCircle is licensed under GPL-3.0-only. See `LICENSE` and `LICENSES/`.