commit 1d031c8c9e5116d459f4b93c4ac925471ff69934 parent 732c95315975310b7679910e114966b62e7ef4c0 Author: triesap <tyson@radroots.org> Date: Mon, 10 Aug 2026 20:23:20 +0000 repo: align HarvestCircle with monorepo ownership - remove capsule-local normative specs, decisions, and qualification copies - retain concise standalone governance and build instructions - reject docs and workflow roots in Git-aware and archive audits - prove source checks remain independent of the parent documentation tree Diffstat:
18 files changed, 33 insertions(+), 595 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md @@ -57,18 +57,15 @@ local artifacts, absolute host paths, or an enclosing monorepo layout. implicit sibling override, dirty source cache, or unrecorded native binary. Local product crates are workspace path dependencies; shared Radroots packages remain immutable public Git dependencies. -- The repository tracks durable public product specifications, decisions, - contributor and security guidance, and qualification evidence. Approved - public surfaces are `README.md`, `NOTICE`, - `CONTRIBUTING.md`, `SECURITY.md`, `LICENSE`, `LICENSES/**`, - `spec/harvestcircle_mvp_v1/**`, `docs/decisions/**`, - and `docs/qualification/**`. These roots are inspected by the same - namespace, secret, generated-output, credential, and symlink rules as source - code. Internal handoffs, RCLDs, migration narratives, and execution records - remain parent-owned. Other `docs/**` and `spec/**` paths are forbidden. All - `.github/**` and `.act/**` paths are forbidden; local workflow orchestration - belongs to the consuming monorepo's governed `.act/**` surface and must call - this capsule's standalone Make targets. +- The repository retains only concise standalone governance and operational + guidance in `README.md`, `NOTICE`, `CONTRIBUTING.md`, `SECURITY.md`, + `LICENSE`, and `LICENSES/**`. Authoritative product specifications, + decisions, reviews, handoffs, and qualification evidence are owned by the + consuming Radroots monorepo under `docs/oss/harvestcircle/**` and must not be + required to build or test this standalone source tree. All `docs/**`, + `spec/**`, `.github/**`, and `.act/**` paths are forbidden here. Local + workflow orchestration belongs to the consuming monorepo's governed + `.act/**` surface and must call this capsule's standalone Make targets. Generated UniFFI Kotlin and native libraries are derived build output. Change the local canonical Rust producer contract/generator first, regenerate into diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md @@ -1,15 +1,11 @@ # Contributing -## Start with the specification +## Start with the repository contract -Read: - -```text -spec/harvestcircle_mvp_v1/ -AGENTS.md -``` - -before changing product behaviour or architecture. +Read `AGENTS.md` before changing product behaviour or architecture. When this +repository is consumed by the Radroots monorepo, also read the relevant +normative material under its `docs/oss/harvestcircle/` tree. Standalone changes +must not add normative documentation roots to this repository. ## Development flow diff --git a/README.md b/README.md @@ -39,17 +39,12 @@ make package Active implementation currently proceeds on `dev`. -## Specifications +## Project documentation -The durable product contract is under: - -```text -spec/harvestcircle_mvp_v1/ -``` - -Accepted architecture and tooling decisions are under `docs/decisions/`, -including the [direct rust-nostr transport decision](docs/decisions/ADR-0011-direct-rust-nostr-transport.md) -and the [Detekt compatibility exception](docs/decisions/ADR-0012-detekt-tooling-exception.md). +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. ## Security diff --git a/app/desktop/src/test/kotlin/org/harvestcircle/architecture/ProductNamespaceGuardTest.kt b/app/desktop/src/test/kotlin/org/harvestcircle/architecture/ProductNamespaceGuardTest.kt @@ -71,6 +71,16 @@ class ProductNamespaceGuardTest { } @Test + fun standaloneRepositoryDoesNotTrackMonorepoDocumentationOrWorkflowRoots() { + val forbiddenRoots = listOf("spec/", "docs/", ".github/", ".act/") + val findings = + trackedFiles(findRepositoryRoot()) + .filter { relative -> forbiddenRoots.any(relative::startsWith) } + + assertEquals(emptyList(), findings.sorted()) + } + + @Test fun trackedSourcesUseTheHarvestCircleNamingContract() { val root = findRepositoryRoot() val contract = root.resolve("AGENTS.md").readText() @@ -124,9 +134,6 @@ class ProductNamespaceGuardTest { .replace("Radroots $legacyDisplayName application work", "") .replace(provenanceException, "") } - if (relative == "spec/harvestcircle_mvp_v1/UI_SURFACE_MAP.md") { - inspected = inspected.replace("round_${legacyProduct}_screen", "") - } if (inspected.lowercase().contains(legacyProduct)) { add("$relative: legacy product name in tracked text") } diff --git a/buildSrc/src/main/kotlin/org/harvestcircle/gradle/FoundationBoundaryAudit.kt b/buildSrc/src/main/kotlin/org/harvestcircle/gradle/FoundationBoundaryAudit.kt @@ -44,6 +44,7 @@ abstract class VerifyFoundationBoundaries : DefaultTask() { .toString(StandardCharsets.UTF_8) .split('\u0000') .filter(String::isNotEmpty) + .filter { Files.exists(root.resolve(it)) } .sorted() } @@ -86,7 +87,7 @@ abstract class VerifyFoundationBoundaries : DefaultTask() { }.isFailure, ) { "Foundation audit accepted negative fixture $path" } } - val symlinkPath = "spec/harvestcircle_mvp_v1/escape.md" + val symlinkPath = "docs/escape.md" check( runCatching { FoundationBoundaryAudit( @@ -141,10 +142,8 @@ private class FoundationBoundaryAudit( findings: MutableList<String>, ) { val normalized = relative.lowercase() - if ((normalized.startsWith("docs/") || normalized.startsWith("spec/") || - normalized.startsWith(".github/") || normalized.startsWith(".act/")) && - !isApprovedPublicPath(normalized) - ) { + if (normalized.startsWith("docs/") || normalized.startsWith("spec/") || + normalized.startsWith(".github/") || normalized.startsWith(".act/")) { findings += "$relative: forbidden repository root" } if (relative in symbolicLinks || Files.isSymbolicLink(root.resolve(relative))) { @@ -189,9 +188,6 @@ private class FoundationBoundaryAudit( .replace("Radroots $legacyDisplayName application work", "") .replace("core/provenance/$legacyProduct-import-v1.toml", "") } - if (relative == "spec/harvestcircle_mvp_v1/UI_SURFACE_MAP.md") { - inspected = inspected.replace("round_${legacyProduct}_screen", "") - } if (inspected.lowercase().contains(legacyProduct)) { findings += "$relative: legacy product name outside the exact provenance allowlist" } @@ -241,16 +237,6 @@ private class FoundationBoundaryAudit( "SECURITY.md", "LICENSE", "LICENSES/GPL-3.0-only.txt", - "spec/harvestcircle_mvp_v1/PRODUCT_SPEC.md", - "spec/harvestcircle_mvp_v1/ARCHITECTURE.md", - "spec/harvestcircle_mvp_v1/IDENTITY_AND_BOOTSTRAP.md", - "spec/harvestcircle_mvp_v1/UI_SURFACE_MAP.md", - "spec/harvestcircle_mvp_v1/UI_COPY_CONTRACT.md", - "spec/harvestcircle_mvp_v1/SECURITY_AND_PRIVACY.md", - "spec/harvestcircle_mvp_v1/ACCEPTANCE_CRITERIA.md", - "docs/decisions/ADR-0008-public-specs-and-ci.md", - "docs/decisions/ADR-0009-canonical-manifest-digests.md", - "docs/decisions/ADR-0010-gap-aware-snapshot-delivery.md", ) (requiredPublicFiles - inventory.toSet()).sorted().forEach { relative -> findings += "$relative: required public repository file is missing" @@ -307,19 +293,6 @@ private class FoundationBoundaryAudit( ) } - private fun isApprovedPublicPath(normalized: String): Boolean = - normalized in - setOf( - "spec", - "spec/harvestcircle_mvp_v1", - "docs", - "docs/decisions", - "docs/qualification", - ) || - normalized.startsWith("spec/harvestcircle_mvp_v1/") || - normalized.startsWith("docs/decisions/") || - normalized.startsWith("docs/qualification/") - private fun isText(relative: String): Boolean { val path = Path.of(relative) return path.extension in textExtensions || path.name in textNames diff --git a/docs/decisions/ADR-0008-public-specs-and-ci.md b/docs/decisions/ADR-0008-public-specs-and-ci.md @@ -1,16 +0,0 @@ -# ADR-0008: Public specs and local verification are repository requirements - -Status: Accepted - -HarvestCircle is an open-source, spec-anchored project intended for public -review and an OpenSats application. - -Durable specs, decisions, and qualification evidence belong in the repository. -The standalone capsule owns portable Make, Gradle, and Cargo verification -commands, but it does not own workflow definitions under `.github/**` or -`.act/**`. - -The consuming monorepo may invoke those commands through governed local-only -workflows under its root `.act/**` surface. Those workflows add orchestration, -not build behavior, and are not a substitute for running the standalone -commands directly. diff --git a/docs/decisions/ADR-0009-canonical-manifest-digests.md b/docs/decisions/ADR-0009-canonical-manifest-digests.md @@ -1,10 +0,0 @@ -# ADR-0009: Manifest digests use canonical semantic serialization - -Status: Accepted - -Raw checkout bytes are not portable across line-ending policies. - -Product and provenance digests are computed from parsed and canonicalized -content. - -LF policy remains a defense in depth, not the digest authority. diff --git a/docs/decisions/ADR-0010-gap-aware-snapshot-delivery.md b/docs/decisions/ADR-0010-gap-aware-snapshot-delivery.md @@ -1,9 +0,0 @@ -# ADR-0010: Snapshot streams are conflated and gap-aware - -Status: Accepted - -Application changes contain complete snapshots. - -The transport may conflate intermediate values, but must preserve the latest -state, check delivery failure, validate predecessor revisions, and resnapshot -on gaps. diff --git a/docs/decisions/ADR-0011-direct-rust-nostr-transport.md b/docs/decisions/ADR-0011-direct-rust-nostr-transport.md @@ -1,60 +0,0 @@ -# ADR-0011: Use direct rust-nostr profile transport - -- Status: Accepted -- Date: 2026-08-10 - -## Context - -HarvestCircle previously reached Nostr through both the shared Radroots -transport crates and the rust-nostr SDK. Commit -`1f8e5728f4815961d7dac0545c2b03464991b592` removed the redundant shared -transport dependency chain and its duplicate registry-sourced rust-nostr -graph. No specific vulnerability identifier is claimed by this decision. - -The profile adapter now depends directly on `nostr`, `nostr-sdk`, and the -test-only `nostr-relay-builder`, all pinned to rust-nostr revision -`5bba5163eb77107f82c4a8262cf29d7f33a73219`. - -## Decision - -HarvestCircle owns its current profile-fetch transport policy locally in -`radroots_harvestcircle_nostr`. The adapter uses the pinned rust-nostr SDK -directly and preserves these application-visible behaviors: - -- only relay endpoints with read capability are queried; -- each readable endpoint receives a bounded kind-0 profile filter; -- the overall operation has a deadline; -- returned events are checked for signature, author, kind, and valid profile - metadata; -- the newest valid event is selected deterministically; and -- partial and complete outcomes remain distinct, including per-relay failure - evidence. - -Local mock-relay tests exercise these semantics without making external relay -availability part of the test contract. - -This is a profile-transport decision only. Domain relay classification and -capability policy remain owned by `radroots_harvestcircle_domain`, and -application orchestration remains owned by -`radroots_harvestcircle_application`. - -## Consequences - -The direct dependency reduces duplicate transport and dependency surfaces, -but HarvestCircle must maintain the adapter, its retry/deadline behavior, and -its tests. Future collective-market transport is not required to use this -profile adapter; it must be selected against the collective protocol and -privacy requirements when those contracts are implemented. - -## Re-adoption criteria - -A reusable transport abstraction may replace this adapter only when it: - -1. uses one revision-pinned and policy-compliant rust-nostr graph; -2. preserves the typed endpoint capability and destination boundary; -3. preserves bounded querying, validation, deterministic selection, and - partial-success evidence; -4. does not introduce private or product-external dependencies into this - public capsule; and -5. passes the capsule's source, dependency, Rust, binding, and integration - verification lanes. diff --git a/docs/decisions/ADR-0012-detekt-tooling-exception.md b/docs/decisions/ADR-0012-detekt-tooling-exception.md @@ -1,48 +0,0 @@ -# ADR-0012: Retain the Detekt alpha compatibility exception - -- Status: Accepted with expiry -- Date: 2026-08-10 -- Owner: HarvestCircle maintainers -- Review date: 2026-11-10 - -## Context - -The build pins Kotlin `2.4.10`, Gradle `9.5.0`, and Detekt -`2.0.0-alpha.5`. Detekt's official compatibility table reports alpha.5 with -Gradle `9.5.1` and Kotlin `2.4.0`, while stable Detekt `1.23.8` is reported -with Gradle `8.12.1` and Kotlin `2.0.21`. - -Sources: - -- <https://detekt.dev/docs/introduction/compatibility/> -- <https://detekt.dev/changelog-2.0.0/> - -Moving to the stable Detekt line would therefore require unrelated Kotlin and -Gradle downgrades rather than a tooling-only replacement. - -## Decision - -Retain Detekt `2.0.0-alpha.5` as a narrowly scoped build-tooling exception. -It is used for static analysis only and is not linked into the HarvestCircle -runtime or packaged application. - -The reviewed risks are alpha API and rule behavior changes, possible plugin -incompatibility, and non-final defaults. They are contained by exact version -pinning, checked-in configuration, deterministic Gradle verification, and the -repository's lint and full-check lanes. - -## Expiry and upgrade trigger - -Re-evaluate this exception no later than 2026-11-10, or earlier when a stable -Detekt release officially supports Kotlin 2.4.x and Gradle 9.x. Replace the -alpha when that stable release: - -1. runs with the pinned Kotlin and Gradle toolchain without unrelated - downgrades; -2. preserves or intentionally migrates the checked-in rule configuration; -3. passes `make lint`, `make check`, and both governed and standalone - verification lanes; and -4. produces no new runtime or packaging dependency. - -If no compatible stable release exists at review time, maintainers must -record a new dated review rather than silently extending this exception. diff --git a/docs/qualification/foundation-completion.md b/docs/qualification/foundation-completion.md @@ -1,203 +0,0 @@ -# Corrective foundation completion report - -## Repository - -- Repository: HarvestCircle standalone capsule at the configured public origin -- Branch: `dev` -- Starting SHA: `1f8e5728f4815961d7dac0545c2b03464991b592` -- Qualified source SHA: `5186bd45d9a368a8ae28c76d36bab45569325a26` -- Qualification record: the commit containing this file -- Final status: source and package workflows are locally qualified through the - consuming monorepo's governed `act` launcher on macOS; the NVD-backed - dependency scan, Developer ID signing, and notarization remain outstanding - -## Commits - -| # | SHA | Message | Verification | -|---|---|---|---| -| 01 | `d0d70bceec67` | `repo: publish the HarvestCircle specifications and governance` | Public-boundary tests and governed source checks passed. | -| 02 | `37cf617f7960` | `ci: execute the public verification lanes` | Workflow contract and verification-lane tests passed. | -| 03 | `6405b6a32ac4` | `build: canonicalize product and provenance digests` | Cross-language canonicalization fixtures and governed checks passed. | -| 04 | `f00a0c900f96` | `product: make the coordinate manifest authoritative` | Coordinate mutation, authority, and governed checks passed. | -| 05 | `a6c7eb3daee5` | `ffi: generate Kotlin compatibility expectations` | Clean generation, mismatch tests, and both binding lanes passed. | -| 06 | `8f5156a06cf6` | `runtime: make snapshot delivery gap-aware` | Delivery, resnapshot, failure, and lifecycle tests passed. | -| 07 | `aa1c9b5a62ea` | `policy: require revision-pinned Git dependencies` | Source-policy tests and cargo-deny source checks passed. | -| 08 | `6c61b08a682f` | `release: complete build information and readiness` | Build-information and strict readiness tests passed. | -| 09 | `23ddedd8f498` | `lifecycle: close application scopes on disposal` | Normal, abrupt, and repeated disposal tests passed. | -| 10 | `77c2e8c31294` | `identity: make signer binding access capability-safe` | Capability and unchanged local-signer behavior tests passed. | -| 11 | `56ff9bcaabc2` | `network: type relay destination policies` | Rust, FFI, desktop parser, compatibility, and binding checks passed. | -| 12 | `0fcc40ffb626` | `architecture: record transport and tooling decisions` | Public documentation and foundation-boundary checks passed. | -| QF-1 | `aff09a20eb5b` | `test: stabilize observer qualification timing` | Observer tests passed 20 consecutive runs; the full governed gate passed. | -| 13 | This record | `release: qualify the corrected HarvestCircle foundation` | Complete local matrix recorded below; external gates remain explicit. | -| QF-2 | `5186bd45d9a3` | `ci: return workflow authority to local orchestration` | The capsule gate and both root-owned local `act` workflows passed. | - -QF-1 is a qualification-time corrective deviation between planned checkpoints -12 and 13. It changes only test timing and observer-cleanup synchronization; it -does not change the public runtime contract. - -## Issue resolution - -| Issue ID | Resolution | Tests/evidence | -|---|---|---| -| HC-FC-001 | Published the bounded public specification/governance surface, removed forbidden capsule workflows, and retained portable standalone verification. | Foundation-boundary, archive, standalone-lane, and root-owned local `act` source/package workflows passed. | -| HC-FC-002 | Rust and Gradle now hash a shared semantic canonical form for product coordinates and provenance. | Cross-language vectors passed, including newline and field-order variants. | -| HC-FC-003 | Snapshot delivery is conflated-latest, revision-aware, and gap-recovering. | Duplicate, stale, burst, gap, refresh-failure, unsubscribe, and observer-cleanup tests passed. | -| HC-FC-004 | The product coordinate manifest is the sole approved-value authority. | Mutation propagation and duplicate-authority audits passed. | -| HC-FC-005 | Kotlin compatibility expectations are generated into ignored build output. | Generation freshness, mismatch tests, tracked-output audit, and both binding lanes passed. | -| HC-FC-006 | This public qualification report records local results and remaining external gates. | Report boundary checks and exact-candidate local workflow proof passed. | -| HC-FC-007 | Git dependencies must be immutable revision pins. | Positive source scan and negative policy fixtures passed. | -| HC-FC-008 | Build information is complete and release readiness fails closed. | Unknown, dirty, malformed, mismatched, and exact clean-provenance cases passed. | -| HC-FC-009 | Application-owned scopes and clipboard resources close on normal and abrupt disposal. | Normal, abrupt, repeated, and late-callback tests passed. | -| HC-FC-010 | Local signer binding access is capability-safe. | Optional capability and unchanged local keyring behavior tests passed. | -| HC-FC-011 | Every relay endpoint has a typed destination and read/write policy. | Configuration, DTO, parser, packaged-policy, mixed-development, FFI, and binding tests passed. | -| HC-FC-012 | ADR-0011 records the direct rust-nostr transport decision and re-adoption criteria. | Public documentation and dependency-source checks passed. | -| HC-FC-013 | ADR-0012 records a bounded Detekt compatibility exception and exit criteria. | Public documentation and Kotlin lint/check lanes passed. | - -## Canonical digests - -- Product digest: - `93bf10e334e989b20ba5fb8ed05e5d55b83f4502efba5f893aef4dc1a66c8223` -- Provenance digest: - `db238195b4a5938a8d4d9ac5681c4b125e65c57aa8133ad03e59da4e4bd062bc` -- Foundation baseline: - `a2038b3e25b9e34f0b8fd001f26a8ed10b5772cb` -- Canonical Radroots revision: - `09065a610d95e57acdc895a14c07580fa099e7c3` -- LF/CRLF vector result: equivalent semantic inputs using LF, CRLF, no final - newline, permitted surrounding whitespace, or reordered fields produced the - same digest. UTF-8 BOM input was rejected as required. - -## FFI - -- Contract ID: `harvestcircle-desktop-ffi-v4` -- Major: `4` -- Minor: `1` -- Hash: - `c7a84960e53cd9df35d676bab28294eb048a8b86c766d81cded2635b64a7f3d6` -- Snapshot schema: `1` -- Storage schema: minimum `5`, current `10` -- Generated Kotlin source: - `app/desktop/build/generated/uniffi/kotlin/org/harvestcircle/ffi/harvestcircle_ffi.kt` - (ignored and reproducible; the governed extbuild lane writes the equivalent - path under its routed build root) - -## Change delivery - -- Conflation strategy: Kotlin consumes a bounded, conflated-latest stream. -- Gap detection: duplicate and stale revisions are ignored; a change whose - previous revision does not equal the accepted revision is a gap. -- Resnapshot behavior: a gap calls `currentSnapshot()` and accepts only a - refreshed revision at or beyond the announced revision. Failure is surfaced - as a typed application problem. -- Burst test: passed, including delayed consumers, stale/duplicate delivery, - resnapshot, observer failure, unsubscribe, and cleanup behavior. - -## BuildInfo - -- Product: HarvestCircle `0.1.0-alpha`; distribution package `1.0.0` -- Toolchains: Rust `1.97.1`, Gradle `9.5.0`, Java `21.0.11`, Kotlin `2.4.10` -- Compose Multiplatform: `1.11.1` -- Registry state: typed `NotApplicable` -- Exact-candidate provenance: source - `5186bd45d9a368a8ae28c76d36bab45569325a26`, clean source, Radroots revision - `09065a610d95e57acdc895a14c07580fa099e7c3`, source epoch `1786389775` -- Release-ready result: passed for the exact clean candidate. Missing or - malformed provenance failed closed as designed. - -## Local workflow proof - -- Authority: workflow definitions are forbidden in this OSS capsule. The - consuming monorepo owns `harvestcircle-source.yml` and - `harvestcircle-package.yml` under its root `.act/workflows/**` surface. -- Launcher: the guarded root launcher requires `act 0.2.89`, rejects arbitrary - lanes, maps only the local macOS runner, derives provenance from the clean - nested Git repository, and invokes this capsule's Make targets. -- Source result: passed for `5186bd45d9a368a8ae28c76d36bab45569325a26` - through `make source-check` in approximately 90 seconds. -- Package result: passed for the same source through `make package-check` in - approximately 98 seconds and produced `HarvestCircle-1.0.0.dmg`. -- Platform scope: macOS is proven on this machine. Linux and Windows package - production require corresponding local hosts or explicitly governed local - virtualized runners; no remote workflow result is claimed. - -## Commands - -| Command or lane | Result | Notes | -|---|---|---| -| `make doctor` | Pass | Extbuild routing and project configuration were healthy. | -| `make format` | Pass | Repository formatting gate passed. | -| `make lint` | Pass | Rust and Kotlin lint gates passed. | -| `make test` | Pass | Full repository test surface passed. | -| Governed and standalone `make check` lanes | Pass | The standalone lane confirms contributor builds do not require extbuild. | -| Governed and standalone binding lanes | Pass | UniFFI bindings and generated compatibility sources were reproducible. | -| `make build` | Pass | Governed build completed. | -| `make licenses` | Pass | Licence report and policy completed. | -| `make source-check` | Pass | Source provenance and source-policy checks completed. | -| `make package` | Pass | macOS produced and verified `HarvestCircle-1.0.0.dmg` (approximately 72 MiB). | -| `make package-check` without provenance | Expected fail | Failed closed because the source commit was unknown. | -| `make package-check` with exact candidate provenance | Pass | Clean source SHA, Radroots revision, and source epoch above were injected explicitly. | -| Root `cto.harvestcircle.all` | Pass | Local `act` source and package jobs both completed successfully on macOS. | -| Rust format, workspace check, Clippy, and workspace tests | Pass | Exact candidate; locked workspace; all targets for Clippy; warnings denied. | -| `cargo deny` source and licence checks | Pass | Revision policy and licence policy passed. | -| Product, compatibility, generated-source, boundary, archive, lane, provenance, shared desktop, and desktop Gradle verification | Pass | Actual scoped Gradle tasks passed together on the exact candidate. | -| Four final prohibited-pattern audits | Pass | No matches in their governed scopes. | -| Generated-output tracking audit | Pass | Desktop/shared/buildSrc outputs and `core/target` were ignored and untracked. | -| `git diff --check` | Pass | No whitespace errors. | -| `make audit` | External blocker | The shared workstation RustSec cache had inconsistent advisory paths; it was not mutated. | -| Isolated fresh RustSec database scan | Pass with warning | No actionable vulnerability failure; `instant 0.1.13` was reported as unmaintained through rust-nostr. | -| OWASP dependency analysis | External blocker | No NVD API key was available and the feed update made no progress during the bounded run; the run was stopped without weakening policy. | - -Two task names in the planning matrix were stale. Repository policy is -integrated into the foundation-boundary task, and generated-source verification -is scoped to the desktop project. The actual authoritative tasks were run and -passed. - -## Signing/notarization - -- Signing: blocked by external release credentials. The local application is - ad-hoc signed; no Developer ID Application signature is claimed. -- Notarization: blocked by external release credentials and service access. - The local DMG has no stapled notarization ticket. - -## Deviations - -- Qualification exposed two load-sensitive observer-test assumptions: a fixed - cleanup delay and an unrealistically short local-relay timeout. QF-1 waits - for the observable cleanup condition and uses a bounded two-second relay - timeout. Twenty consecutive focused runs and the full governed gate passed. -- The planned public-contract and generated-source Gradle task names did not - match the implemented authority. Their integrated/scoped equivalents were - run and passed; no check was removed. -- The shared RustSec cache failure was isolated from source correctness. A - fresh official advisory database supplied supplemental evidence without - mutating shared workstation state. -- The NVD-backed scan remains externally blocked by feed access. It is not - represented as green. -- Package readiness intentionally requires explicit source provenance. The - unqualified invocation failed closed, and the exact-candidate invocation - passed. -- The original remote workflow design was superseded by the repository-wide - rule that forbids `.github/**` in every OSS capsule. QF-2 removes those files - and moves orchestration to guarded root-owned local `act` workflows without - moving build behavior out of this capsule. - -## Unresolved issues - -- Push the qualification lineage to `origin/dev` under separate authorization. -- Exercise Linux and Windows package production on corresponding governed - local hosts or local virtualized runners if cross-platform package proof is - required before release. -- Provide reliable NVD feed access or an API key, then rerun the OWASP-backed - dependency analysis. -- Provide Developer ID credentials and notarization service access before any - release claim that requires signed and notarized macOS media. -- Update this evidence after any additional platform or external release gates - complete. - -## Safe to begin next handoff - -Yes, for separately authorized product-shell source work. The exact source and -macOS package workflows are proven locally through the governed root `act` -launcher. This does not authorize a production release, and the external -security-feed, signing, notarization, Linux, and Windows gates above remain -explicit. diff --git a/spec/harvestcircle_mvp_v1/ACCEPTANCE_CRITERIA.md b/spec/harvestcircle_mvp_v1/ACCEPTANCE_CRITERIA.md @@ -1,16 +0,0 @@ -# Acceptance criteria - -The foundation is complete when: - -- public specs/governance and portable standalone verification exist; -- product/provenance digests are canonical; -- coordinate values have one authority; -- Kotlin compatibility expectations are generated; -- change delivery is gap-aware; -- Git sources require rev; -- BuildInfo/readiness is complete; -- scopes close safely; -- signer-binding access is future-safe; -- relay destinations are explicit; -- architecture decisions are documented; -- complete qualification evidence is public. diff --git a/spec/harvestcircle_mvp_v1/ARCHITECTURE.md b/spec/harvestcircle_mvp_v1/ARCHITECTURE.md @@ -1,39 +0,0 @@ -# Architecture - -```text -app:shared - KMP common application models, presenters, shared Compose - ↓ platform-neutral runtime interface -app:desktop - desktop host, generated UniFFI adapter, JNA/AWT, packaging - ↓ -Rust HarvestCircle application/runtime/storage/Nostr/FFI crates - ↓ -canonical public Radroots libraries -``` - -Rust owns canonical identity, persistence, operation, Nostr, compatibility, -and future commercial protocol state. - -Kotlin shared code owns presentation state and platform-neutral use cases. - -Generated FFI types remain in the desktop adapter. - -No silent fallback, duplicated commercial model, or UI-thread blocking. - -## Relay bootstrap - -Every relay endpoint carries an explicit destination (`Local`, -`PrivateNetwork`, or `Public`) and independent read/write capabilities. Rust -owns URL, destination, uniqueness, and capability validation; the desktop host -only adapts environment input into the typed UniFFI record. - -Development input uses deterministic comma-separated entries: - -```text -HARVESTCIRCLE_NOSTR_RELAYS=local|ws://127.0.0.1:8080,public|wss://relay.example -``` - -The `private|` prefix selects `PrivateNetwork`. Current desktop entries enable -both reading and writing. Missing packaged configuration remains a visible -degraded-network state and never invents or reclassifies a relay. diff --git a/spec/harvestcircle_mvp_v1/IDENTITY_AND_BOOTSTRAP.md b/spec/harvestcircle_mvp_v1/IDENTITY_AND_BOOTSTRAP.md @@ -1,27 +0,0 @@ -# Identity and bootstrap - -Preserve: - -- local Nostr identity generation; -- one-use recovery; -- acknowledgment before persistence; -- local secret import; -- OS-keyring custody; -- activation, switching, sign-out, removal, and repair. - -Identity and signer binding are separate. - -Current signer binding: - -```text -LocalKeyring -``` - -Future: - -```text -RemoteNip46 -ReadOnly -``` - -Future variants are not implemented during foundation completion. diff --git a/spec/harvestcircle_mvp_v1/PRODUCT_SPEC.md b/spec/harvestcircle_mvp_v1/PRODUCT_SPEC.md @@ -1,29 +0,0 @@ -# HarvestCircle MVP v1 - -HarvestCircle coordinates one local-food buying-circle round between a farm -and nearby buyers without requiring a central product marketplace. - -The eventual desktop MVP proves: - -- one signed farm produce-box round; -- private buyer maximum-price commitments; -- authority admission and deterministic clearing; -- private allocation; -- pay-at-pickup fulfilment; -- buyer acknowledgment; -- inspectable Nostr/Radroots evidence. - -Initial commercial constraints: - -- one farm; -- one standardized produce box; -- two price levels; -- one pickup window; -- CAD; -- one or two boxes per buyer; -- pay at pickup; -- farm-provided comparison; -- no custody, delivery, or multi-farm cart. - -The current foundation phase preserves local Nostr identity security and builds -the KMP/Rust platform required for that MVP. diff --git a/spec/harvestcircle_mvp_v1/SECURITY_AND_PRIVACY.md b/spec/harvestcircle_mvp_v1/SECURITY_AND_PRIVACY.md @@ -1,13 +0,0 @@ -# Security and privacy - -- no plaintext secret fallback; -- one-use generated recovery; -- bounded and cleared import buffers; -- no secret logs or diagnostics; -- compatibility before storage open; -- exact native artifact; -- UUIDv7 durable operation IDs; -- no silent provider fallback; -- no private event through public sinks; -- unknown protocol versions fail closed; -- local workflow orchestration is parent-owned, credential-free, and fail-closed. diff --git a/spec/harvestcircle_mvp_v1/UI_COPY_CONTRACT.md b/spec/harvestcircle_mvp_v1/UI_COPY_CONTRACT.md @@ -1,24 +0,0 @@ -# UI copy contract - -Voice: - -- calm; -- factual; -- concise; -- sentence case; -- no exclamation marks; -- no hype or artificial urgency; -- explicit actor and state; -- explicit public/private visibility; -- explicit uncertainty. - -Use: - -- Nostr identity -- buying circle -- commitment admitted -- delivery incomplete -- farm-provided comparison -- inspect proof - -Do not claim independently verified savings in the MVP. diff --git a/spec/harvestcircle_mvp_v1/UI_SURFACE_MAP.md b/spec/harvestcircle_mvp_v1/UI_SURFACE_MAP.md @@ -1,36 +0,0 @@ -# UI surface reference - -The future desktop MVP uses: - -- dashboard layout with fixed sidebar/top bar/main header; -- canvas layout for focused workflows; -- nested views rather than one long scrolling dashboard page. - -Locked screen keys: - -```text -bootstrap_screen -signer_connection_screen -startup_recovery_screen -runtime_recovery_screen -protocol_compatibility_screen -signing_review_screen -proof_chain_screen -fulfillment_issue_screen -personal_today_screen -explore_screen -farm_profile_screen -circle_screen -activity_screen -commitment_screen -allocation_screen -farm_overview_screen -round_studio_screen -live_round_screen -pickup_desk_screen -round_outcome_screen -network_screen -settings_screen -``` - -Foundation completion does not implement these product screens.