HarvestCircle is an open-source Nostr application for coordinating local-food buying circles.
The project is in early desktop development. It is not ready for real commercial use.
- Kotlin Multiplatform shared application code;
- Compose Desktop host;
- product-specific Rust core through UniFFI;
- local Nostr identity creation and import;
- operating-system keyring custody;
- canonical service-instance persistence through the governed SQLx host;
- configurable Nostr relay bootstrap;
- compatibility-gated native startup;
- reproducible source and development qualification.
The MVP is designed to work without a managed HarvestCircle account or API.
Future work adds canonical Radroots collective-market contracts, private buyer commitments, a selectable open reference authority, pickup, and proof.
Prerequisites include JDK 21, Rust 1.97.1, and platform packaging tools.
make doctor
make check
make build
make governed-development-checkThese commands always use the standalone contributor lane. Use
make governed-check or make governed-integration-check when a narrower
extbuild-governed lane is required. The full active development milestone uses
make governed-development-check on macOS aarch64 and
make governed-linux-x86_64-development-check for Linux x86_64. It verifies
source, runtime, generated bindings, the public storage API, the exact Radroots
source lock, the single SQLx-selected SQLite linkage, and offline license/source
policy. Network advisory services, package assembly, release evidence, signing,
notarization, Nix, and OCI qualification remain deferred and unclaimed until a
release candidate is declared with fresh authority.
Active implementation proceeds on master.
HarvestCircle derives one canonical harvestcircle/desktop runtime context
and stores application state only in its governed state.sqlite service
database. SQLx is the sole high-level SQLite library, while
radroots_service_sqlite owns connection, authority, migration, integrity,
close, backup, and restore mechanics. The historical harvestcircle.sqlite3
file is legacy evidence only and is never imported, repaired, deleted, or
treated as current state.
The platform or development harness must supply the existing canonical state
root. HarvestCircle then uses the runtime context's sealed provisioning plan to
create or validate only services/harvestcircle/desktop. The SQLite host makes
the create-versus-existing decision atomically and returns the actual verified
metadata; product storage never probes the database path, recursively creates
roots, repairs existing permissions, or opens a raw SQLx connection.
Online backup capture returns the canonical manifest in memory and writes only
the governed state.sqlite member into a caller-selected new directory.
Restore accepts only a digest-bound, identity-bound, size-bounded verified
backup capability, closes the live host, uses the governed marker protocol,
and reopens recovered state before returning. There is no arbitrary database
repair or pathname-only restore authority.
Relay endpoints are explicit inputs validated by the pinned Radroots Nostr transport policy before any socket work. HarvestCircle owns profile selection and signature-verified kind-0 interpretation, while the shared transport owns relay URL, destination, DNS, connection, and bounded-fetch behavior. The native FFI host owns one runtime per application core and closes it idempotently. Cancelling a close never reopens command admission, and a later close call resumes the same shutdown. Operating-system keyring calls run through an object-safe asynchronous application port and a bounded supervised worker rather than directly on an async runtime worker. Callers await one-shot responses; the dedicated operating-system thread alone drives the blocking platform adapter. Its request queue is fixed at eight entries and credential mutations carry the caller's canonical UUIDv7 durable request identity. Work cancelled while still queued has no credential effect; caller loss after work starts is an unknown outcome reconciled from the durable operation journal. Shutdown has a fixed 30-second wait and reports success only after the worker thread is joined; a timeout remains recovery-required and a later close resumes the same drain.
Credential creation is native and atomic: macOS uses create-only Keychain insertion, while Linux uses Secret Service creation with replacement disabled. The stored zeroizing envelope binds the creating durable operation to the secret. Exact same-operation replay is idempotent only when the complete envelope matches; another operation conflicts and never overwrites the existing credential. No compatibility path reads the former plaintext credential shape.
The state database initializes at schema v1 and applies the pinned schema-v2 operation-journal migration before the host is exposed. Terminal receipts carry an explicit completion time and remain replayable for exactly seven days. Admission caps unfinished operations at 1,024 and all journal rows at 4,096, deletes at most 256 expired terminal receipts in one transaction, reserves each accepted operation's terminal row in place, and never evicts an in-window receipt. The migration, resulting table and guards, and both schema snapshots are checksum-pinned; invalid legacy rows roll the migration back atomically.
The consuming Radroots monorepo owns normative HarvestCircle specifications,
decisions, handoffs, reviews, and qualification evidence under
docs/oss/harvestcircle/. This standalone source tree remains independently
buildable and testable without that documentation tree.
Do not submit secret keys, nsec values, signer secrets, or decrypted private contracts in issues or logs.
See SECURITY.md.
HarvestCircle is licensed under GPL-3.0-only. See LICENSE and LICENSES/.